mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Compare commits
1 Commits
alpha-1.4.
...
feature-fl
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
934997ed91 |
@@ -83,8 +83,7 @@ android test:
|
|||||||
test_reproducible:
|
test_reproducible:
|
||||||
stage: check_reproducibility
|
stage: check_reproducibility
|
||||||
script:
|
script:
|
||||||
- "curl -X POST -F token=${RELEASE_CHECK_TOKEN} -F ref=master -F variables[APP]='briar' -F variables[RELEASE_TAG]=${CI_COMMIT_REF_NAME} https://code.briarproject.org/api/v4/projects/61/trigger/pipeline"
|
- "curl -X POST -F token=${RELEASE_CHECK_TOKEN} -F ref=master -F variables[RELEASE_TAG]=${CI_COMMIT_REF_NAME} https://code.briarproject.org/api/v4/projects/61/trigger/pipeline"
|
||||||
- "curl -X POST -F token=${RELEASE_JAR_CHECK_TOKEN} -F ref=main -F variables[APP]='briar-headless' -F variables[RELEASE_TAG]=${CI_COMMIT_REF_NAME} https://code.briarproject.org/api/v4/projects/307/trigger/pipeline"
|
|
||||||
only:
|
only:
|
||||||
- tags
|
- tags
|
||||||
|
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 31
|
targetSdkVersion 31
|
||||||
versionCode 10423
|
versionCode 10420
|
||||||
versionName "1.4.23"
|
versionName "1.4.20"
|
||||||
consumerProguardFiles 'proguard-rules.txt'
|
consumerProguardFiles 'proguard-rules.txt'
|
||||||
|
|
||||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||||
@@ -71,7 +71,7 @@ def torLibsDir = 'src/main/jniLibs'
|
|||||||
task cleanTorBinaries {
|
task cleanTorBinaries {
|
||||||
outputs.dir torLibsDir
|
outputs.dir torLibsDir
|
||||||
doLast {
|
doLast {
|
||||||
delete fileTree(torLibsDir)
|
delete fileTree(torLibsDir) { include '**/*.so' }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -80,9 +80,34 @@ clean.dependsOn cleanTorBinaries
|
|||||||
task unpackTorBinaries {
|
task unpackTorBinaries {
|
||||||
outputs.dir torLibsDir
|
outputs.dir torLibsDir
|
||||||
doLast {
|
doLast {
|
||||||
copy {
|
configurations.tor.each { outer ->
|
||||||
from configurations.tor.collect { zipTree(it) }
|
zipTree(outer).each { inner ->
|
||||||
into torLibsDir
|
if (inner.name.endsWith('_arm_pie.zip')) {
|
||||||
|
copy {
|
||||||
|
from zipTree(inner)
|
||||||
|
into torLibsDir
|
||||||
|
rename '(.*)', 'armeabi-v7a/lib$1.so'
|
||||||
|
}
|
||||||
|
} else if (inner.name.endsWith('_arm64_pie.zip')) {
|
||||||
|
copy {
|
||||||
|
from zipTree(inner)
|
||||||
|
into torLibsDir
|
||||||
|
rename '(.*)', 'arm64-v8a/lib$1.so'
|
||||||
|
}
|
||||||
|
} else if (inner.name.endsWith('_x86_pie.zip')) {
|
||||||
|
copy {
|
||||||
|
from zipTree(inner)
|
||||||
|
into torLibsDir
|
||||||
|
rename '(.*)', 'x86/lib$1.so'
|
||||||
|
}
|
||||||
|
} else if (inner.name.endsWith('_x86_64_pie.zip')) {
|
||||||
|
copy {
|
||||||
|
from zipTree(inner)
|
||||||
|
into torLibsDir
|
||||||
|
rename '(.*)', 'x86_64/lib$1.so'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dependsOn cleanTorBinaries
|
dependsOn cleanTorBinaries
|
||||||
|
|||||||
@@ -33,10 +33,8 @@ class AndroidBluetoothTransportConnection
|
|||||||
super(plugin);
|
super(plugin);
|
||||||
this.connectionLimiter = connectionLimiter;
|
this.connectionLimiter = connectionLimiter;
|
||||||
this.socket = socket;
|
this.socket = socket;
|
||||||
InputStream socketIn = socket.getInputStream();
|
in = timeoutMonitor.createTimeoutInputStream(
|
||||||
if (socketIn == null) throw new IOException();
|
socket.getInputStream(), plugin.getMaxIdleTime() * 2);
|
||||||
in = timeoutMonitor.createTimeoutInputStream(socketIn,
|
|
||||||
plugin.getMaxIdleTime() * 2L);
|
|
||||||
wakeLock = wakeLockManager.createWakeLock("BluetoothConnection");
|
wakeLock = wakeLockManager.createWakeLock("BluetoothConnection");
|
||||||
wakeLock.acquire();
|
wakeLock.acquire();
|
||||||
String address = socket.getRemoteDevice().getAddress();
|
String address = socket.getRemoteDevice().getAddress();
|
||||||
@@ -50,9 +48,7 @@ class AndroidBluetoothTransportConnection
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected OutputStream getOutputStream() throws IOException {
|
protected OutputStream getOutputStream() throws IOException {
|
||||||
OutputStream socketOut = socket.getOutputStream();
|
return socket.getOutputStream();
|
||||||
if (socketOut == null) throw new IOException();
|
|
||||||
return socketOut;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,9 +24,9 @@ dependencyVerification {
|
|||||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||||
'org.briarproject:obfs4proxy-android:0.0.14-tor2:obfs4proxy-android-0.0.14-tor2.jar:a0a93770d6760ce57d9dbd31cc7177687374e00c3361dac22ab75e3b6e0f289e',
|
'org.briarproject:obfs4proxy-android:0.0.14-tor1:obfs4proxy-android-0.0.14-tor1.jar:8b08068778b133484b17956d8f7a7710739c33f671a26a68156f4d34e6f28c30',
|
||||||
'org.briarproject:snowflake-android:2.5.1:snowflake-android-2.5.1.jar:88ec81c17b1b6fa884d06839dec0330e328b45c89f88c970a213ce91ca8eac87',
|
'org.briarproject:snowflake-android:2.3.1:snowflake-android-2.3.1.jar:1f83c9a070f87b7074af13627709a8b5aced5460104be7166af736b1bb73c293',
|
||||||
'org.briarproject:tor-android:0.4.7.13-2:tor-android-0.4.7.13-2.jar:453fd463b234a2104edd7f0d02d0649cbb5c5efbe47a76df3828f55a3f90f8b5',
|
'org.briarproject:tor-android:0.4.7.13:tor-android-0.4.7.13.jar:7852aab7d2298b80878c7719f34ce665725b494d673ecf2e6f9e697564638cc6',
|
||||||
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
|
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
|
||||||
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
|
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
|
||||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||||
|
|||||||
@@ -16,7 +16,6 @@ import java.util.logging.Logger;
|
|||||||
|
|
||||||
import javax.annotation.concurrent.Immutable;
|
import javax.annotation.concurrent.Immutable;
|
||||||
|
|
||||||
import static java.util.logging.Logger.getLogger;
|
|
||||||
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@@ -24,24 +23,17 @@ import static org.briarproject.bramble.api.transport.TransportConstants.MAX_CLOC
|
|||||||
public abstract class BdfMessageValidator implements MessageValidator {
|
public abstract class BdfMessageValidator implements MessageValidator {
|
||||||
|
|
||||||
protected static final Logger LOG =
|
protected static final Logger LOG =
|
||||||
getLogger(BdfMessageValidator.class.getName());
|
Logger.getLogger(BdfMessageValidator.class.getName());
|
||||||
|
|
||||||
protected final ClientHelper clientHelper;
|
protected final ClientHelper clientHelper;
|
||||||
protected final MetadataEncoder metadataEncoder;
|
protected final MetadataEncoder metadataEncoder;
|
||||||
protected final Clock clock;
|
protected final Clock clock;
|
||||||
protected final boolean canonical;
|
|
||||||
|
|
||||||
protected BdfMessageValidator(ClientHelper clientHelper,
|
|
||||||
MetadataEncoder metadataEncoder, Clock clock, boolean canonical) {
|
|
||||||
this.clientHelper = clientHelper;
|
|
||||||
this.metadataEncoder = metadataEncoder;
|
|
||||||
this.clock = clock;
|
|
||||||
this.canonical = canonical;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected BdfMessageValidator(ClientHelper clientHelper,
|
protected BdfMessageValidator(ClientHelper clientHelper,
|
||||||
MetadataEncoder metadataEncoder, Clock clock) {
|
MetadataEncoder metadataEncoder, Clock clock) {
|
||||||
this(clientHelper, metadataEncoder, clock, true);
|
this.clientHelper = clientHelper;
|
||||||
|
this.metadataEncoder = metadataEncoder;
|
||||||
|
this.clock = clock;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected abstract BdfMessageContext validateMessage(Message m, Group g,
|
protected abstract BdfMessageContext validateMessage(Message m, Group g,
|
||||||
@@ -57,7 +49,7 @@ public abstract class BdfMessageValidator implements MessageValidator {
|
|||||||
"Timestamp is too far in the future");
|
"Timestamp is too far in the future");
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
BdfList bodyList = clientHelper.toList(m, canonical);
|
BdfList bodyList = clientHelper.toList(m.getBody());
|
||||||
BdfMessageContext result = validateMessage(m, g, bodyList);
|
BdfMessageContext result = validateMessage(m, g, bodyList);
|
||||||
Metadata meta = metadataEncoder.encode(result.getDictionary());
|
Metadata meta = metadataEncoder.encode(result.getDictionary());
|
||||||
return new MessageContext(meta, result.getDependencies());
|
return new MessageContext(meta, result.getDependencies());
|
||||||
|
|||||||
@@ -49,9 +49,6 @@ public interface ClientHelper {
|
|||||||
BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException,
|
BdfList getMessageAsList(Transaction txn, MessageId m) throws DbException,
|
||||||
FormatException;
|
FormatException;
|
||||||
|
|
||||||
BdfList getMessageAsList(Transaction txn, MessageId m, boolean canonical)
|
|
||||||
throws DbException, FormatException;
|
|
||||||
|
|
||||||
BdfDictionary getGroupMetadataAsDictionary(GroupId g) throws DbException,
|
BdfDictionary getGroupMetadataAsDictionary(GroupId g) throws DbException,
|
||||||
FormatException;
|
FormatException;
|
||||||
|
|
||||||
@@ -109,8 +106,6 @@ public interface ClientHelper {
|
|||||||
|
|
||||||
BdfList toList(Message m) throws FormatException;
|
BdfList toList(Message m) throws FormatException;
|
||||||
|
|
||||||
BdfList toList(Message m, boolean canonical) throws FormatException;
|
|
||||||
|
|
||||||
BdfList toList(Author a);
|
BdfList toList(Author a);
|
||||||
|
|
||||||
byte[] sign(String label, BdfList toSign, PrivateKey privateKey)
|
byte[] sign(String label, BdfList toSign, PrivateKey privateKey)
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import javax.annotation.Nullable;
|
|||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
public final class BdfDictionary extends TreeMap<String, Object> {
|
public class BdfDictionary extends TreeMap<String, Object> {
|
||||||
|
|
||||||
public static final Object NULL_VALUE = new Object();
|
public static final Object NULL_VALUE = new Object();
|
||||||
|
|
||||||
@@ -39,9 +39,9 @@ public final class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getBoolean(String key) throws FormatException {
|
public Boolean getBoolean(String key) throws FormatException {
|
||||||
Boolean value = getOptionalBoolean(key);
|
Object o = get(key);
|
||||||
if (value == null) throw new FormatException();
|
if (o instanceof Boolean) return (Boolean) o;
|
||||||
return value;
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -52,16 +52,19 @@ public final class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getBoolean(String key, Boolean defaultValue)
|
public Boolean getBoolean(String key, Boolean defaultValue) {
|
||||||
throws FormatException {
|
Object o = get(key);
|
||||||
Boolean value = getOptionalBoolean(key);
|
if (o instanceof Boolean) return (Boolean) o;
|
||||||
return value == null ? defaultValue : value;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLong(String key) throws FormatException {
|
public Long getLong(String key) throws FormatException {
|
||||||
Long value = getOptionalLong(key);
|
Object o = get(key);
|
||||||
if (value == null) throw new FormatException();
|
if (o instanceof Long) return (Long) o;
|
||||||
return value;
|
if (o instanceof Integer) return ((Integer) o).longValue();
|
||||||
|
if (o instanceof Short) return ((Short) o).longValue();
|
||||||
|
if (o instanceof Byte) return ((Byte) o).longValue();
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -75,37 +78,20 @@ public final class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLong(String key, Long defaultValue) throws FormatException {
|
public Long getLong(String key, Long defaultValue) {
|
||||||
Long value = getOptionalLong(key);
|
Object o = get(key);
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof Long) return (Long) o;
|
||||||
}
|
if (o instanceof Integer) return ((Integer) o).longValue();
|
||||||
|
if (o instanceof Short) return ((Short) o).longValue();
|
||||||
public Integer getInt(String key) throws FormatException {
|
if (o instanceof Byte) return ((Byte) o).longValue();
|
||||||
Integer value = getOptionalInt(key);
|
return defaultValue;
|
||||||
if (value == null) throw new FormatException();
|
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Integer getOptionalInt(String key) throws FormatException {
|
|
||||||
Long value = getOptionalLong(key);
|
|
||||||
if (value == null) return null;
|
|
||||||
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
return value.intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getInt(String key, Integer defaultValue)
|
|
||||||
throws FormatException {
|
|
||||||
Integer value = getOptionalInt(key);
|
|
||||||
return value == null ? defaultValue : value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getDouble(String key) throws FormatException {
|
public Double getDouble(String key) throws FormatException {
|
||||||
Double value = getOptionalDouble(key);
|
Object o = get(key);
|
||||||
if (value == null) throw new FormatException();
|
if (o instanceof Double) return (Double) o;
|
||||||
return value;
|
if (o instanceof Float) return ((Float) o).doubleValue();
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -117,16 +103,17 @@ public final class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getDouble(String key, Double defaultValue)
|
public Double getDouble(String key, Double defaultValue) {
|
||||||
throws FormatException {
|
Object o = get(key);
|
||||||
Double value = getOptionalDouble(key);
|
if (o instanceof Double) return (Double) o;
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof Float) return ((Float) o).doubleValue();
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(String key) throws FormatException {
|
public String getString(String key) throws FormatException {
|
||||||
String value = getOptionalString(key);
|
Object o = get(key);
|
||||||
if (value == null) throw new FormatException();
|
if (o instanceof String) return (String) o;
|
||||||
return value;
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -137,16 +124,17 @@ public final class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(String key, String defaultValue)
|
public String getString(String key, String defaultValue) {
|
||||||
throws FormatException {
|
Object o = get(key);
|
||||||
String value = getOptionalString(key);
|
if (o instanceof String) return (String) o;
|
||||||
return value == null ? defaultValue : value;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getRaw(String key) throws FormatException {
|
public byte[] getRaw(String key) throws FormatException {
|
||||||
byte[] value = getOptionalRaw(key);
|
Object o = get(key);
|
||||||
if (value == null) throw new FormatException();
|
if (o instanceof byte[]) return (byte[]) o;
|
||||||
return value;
|
if (o instanceof Bytes) return ((Bytes) o).getBytes();
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -158,16 +146,17 @@ public final class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getRaw(String key, byte[] defaultValue)
|
public byte[] getRaw(String key, byte[] defaultValue) {
|
||||||
throws FormatException {
|
Object o = get(key);
|
||||||
byte[] value = getOptionalRaw(key);
|
if (o instanceof byte[]) return (byte[]) o;
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof Bytes) return ((Bytes) o).getBytes();
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfList getList(String key) throws FormatException {
|
public BdfList getList(String key) throws FormatException {
|
||||||
BdfList value = getOptionalList(key);
|
Object o = get(key);
|
||||||
if (value == null) throw new FormatException();
|
if (o instanceof BdfList) return (BdfList) o;
|
||||||
return value;
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -178,16 +167,16 @@ public final class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfList getList(String key, BdfList defaultValue)
|
public BdfList getList(String key, BdfList defaultValue) {
|
||||||
throws FormatException {
|
Object o = get(key);
|
||||||
BdfList value = getOptionalList(key);
|
if (o instanceof BdfList) return (BdfList) o;
|
||||||
return value == null ? defaultValue : value;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfDictionary getDictionary(String key) throws FormatException {
|
public BdfDictionary getDictionary(String key) throws FormatException {
|
||||||
BdfDictionary value = getOptionalDictionary(key);
|
Object o = get(key);
|
||||||
if (value == null) throw new FormatException();
|
if (o instanceof BdfDictionary) return (BdfDictionary) o;
|
||||||
return value;
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -199,9 +188,9 @@ public final class BdfDictionary extends TreeMap<String, Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfDictionary getDictionary(String key, BdfDictionary defaultValue)
|
public BdfDictionary getDictionary(String key, BdfDictionary defaultValue) {
|
||||||
throws FormatException {
|
Object o = get(key);
|
||||||
BdfDictionary value = getOptionalDictionary(key);
|
if (o instanceof BdfDictionary) return (BdfDictionary) o;
|
||||||
return value == null ? defaultValue : value;
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import javax.annotation.concurrent.NotThreadSafe;
|
|||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
public final class BdfList extends ArrayList<Object> {
|
public class BdfList extends ArrayList<Object> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Factory method for constructing lists inline.
|
* Factory method for constructing lists inline.
|
||||||
@@ -33,15 +33,15 @@ public final class BdfList extends ArrayList<Object> {
|
|||||||
super(items);
|
super(items);
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
|
|
||||||
private boolean isInRange(int index) {
|
private boolean isInRange(int index) {
|
||||||
return index >= 0 && index < size();
|
return index >= 0 && index < size();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getBoolean(int index) throws FormatException {
|
public Boolean getBoolean(int index) throws FormatException {
|
||||||
Boolean value = getOptionalBoolean(index);
|
if (!isInRange(index)) throw new FormatException();
|
||||||
if (value == null) throw new FormatException();
|
Object o = get(index);
|
||||||
return value;
|
if (o instanceof Boolean) return (Boolean) o;
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -53,16 +53,21 @@ public final class BdfList extends ArrayList<Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Boolean getBoolean(int index, Boolean defaultValue)
|
public Boolean getBoolean(int index, Boolean defaultValue) {
|
||||||
throws FormatException {
|
if (!isInRange(index)) return defaultValue;
|
||||||
Boolean value = getOptionalBoolean(index);
|
Object o = get(index);
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof Boolean) return (Boolean) o;
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLong(int index) throws FormatException {
|
public Long getLong(int index) throws FormatException {
|
||||||
Long value = getOptionalLong(index);
|
if (!isInRange(index)) throw new FormatException();
|
||||||
if (value == null) throw new FormatException();
|
Object o = get(index);
|
||||||
return value;
|
if (o instanceof Long) return (Long) o;
|
||||||
|
if (o instanceof Integer) return ((Integer) o).longValue();
|
||||||
|
if (o instanceof Short) return ((Short) o).longValue();
|
||||||
|
if (o instanceof Byte) return ((Byte) o).longValue();
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -77,37 +82,22 @@ public final class BdfList extends ArrayList<Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Long getLong(int index, Long defaultValue) throws FormatException {
|
public Long getLong(int index, Long defaultValue) {
|
||||||
Long value = getOptionalLong(index);
|
if (!isInRange(index)) return defaultValue;
|
||||||
return value == null ? defaultValue : value;
|
Object o = get(index);
|
||||||
}
|
if (o instanceof Long) return (Long) o;
|
||||||
|
if (o instanceof Integer) return ((Integer) o).longValue();
|
||||||
public Integer getInt(int index) throws FormatException {
|
if (o instanceof Short) return ((Short) o).longValue();
|
||||||
Integer value = getOptionalInt(index);
|
if (o instanceof Byte) return ((Byte) o).longValue();
|
||||||
if (value == null) throw new FormatException();
|
return defaultValue;
|
||||||
return value;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
public Integer getOptionalInt(int index) throws FormatException {
|
|
||||||
Long value = getOptionalLong(index);
|
|
||||||
if (value == null) return null;
|
|
||||||
if (value < Integer.MIN_VALUE || value > Integer.MAX_VALUE) {
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
return value.intValue();
|
|
||||||
}
|
|
||||||
|
|
||||||
public Integer getInt(int index, Integer defaultValue)
|
|
||||||
throws FormatException {
|
|
||||||
Integer value = getOptionalInt(index);
|
|
||||||
return value == null ? defaultValue : value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getDouble(int index) throws FormatException {
|
public Double getDouble(int index) throws FormatException {
|
||||||
Double value = getOptionalDouble(index);
|
if (!isInRange(index)) throw new FormatException();
|
||||||
if (value == null) throw new FormatException();
|
Object o = get(index);
|
||||||
return value;
|
if (o instanceof Double) return (Double) o;
|
||||||
|
if (o instanceof Float) return ((Float) o).doubleValue();
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -120,16 +110,19 @@ public final class BdfList extends ArrayList<Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Double getDouble(int index, Double defaultValue)
|
public Double getDouble(int index, Double defaultValue) {
|
||||||
throws FormatException {
|
if (!isInRange(index)) return defaultValue;
|
||||||
Double value = getOptionalDouble(index);
|
Object o = get(index);
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof Double) return (Double) o;
|
||||||
|
if (o instanceof Float) return ((Float) o).doubleValue();
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(int index) throws FormatException {
|
public String getString(int index) throws FormatException {
|
||||||
String value = getOptionalString(index);
|
if (!isInRange(index)) throw new FormatException();
|
||||||
if (value == null) throw new FormatException();
|
Object o = get(index);
|
||||||
return value;
|
if (o instanceof String) return (String) o;
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -141,16 +134,19 @@ public final class BdfList extends ArrayList<Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getString(int index, String defaultValue)
|
public String getString(int index, String defaultValue) {
|
||||||
throws FormatException {
|
if (!isInRange(index)) return defaultValue;
|
||||||
String value = getOptionalString(index);
|
Object o = get(index);
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof String) return (String) o;
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getRaw(int index) throws FormatException {
|
public byte[] getRaw(int index) throws FormatException {
|
||||||
byte[] value = getOptionalRaw(index);
|
if (!isInRange(index)) throw new FormatException();
|
||||||
if (value == null) throw new FormatException();
|
Object o = get(index);
|
||||||
return value;
|
if (o instanceof byte[]) return (byte[]) o;
|
||||||
|
if (o instanceof Bytes) return ((Bytes) o).getBytes();
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -163,16 +159,19 @@ public final class BdfList extends ArrayList<Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getRaw(int index, byte[] defaultValue)
|
public byte[] getRaw(int index, byte[] defaultValue) {
|
||||||
throws FormatException {
|
if (!isInRange(index)) return defaultValue;
|
||||||
byte[] value = getOptionalRaw(index);
|
Object o = get(index);
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof byte[]) return (byte[]) o;
|
||||||
|
if (o instanceof Bytes) return ((Bytes) o).getBytes();
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfList getList(int index) throws FormatException {
|
public BdfList getList(int index) throws FormatException {
|
||||||
BdfList value = getOptionalList(index);
|
if (!isInRange(index)) throw new FormatException();
|
||||||
if (value == null) throw new FormatException();
|
Object o = get(index);
|
||||||
return value;
|
if (o instanceof BdfList) return (BdfList) o;
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -184,16 +183,18 @@ public final class BdfList extends ArrayList<Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfList getList(int index, BdfList defaultValue)
|
public BdfList getList(int index, BdfList defaultValue) {
|
||||||
throws FormatException {
|
if (!isInRange(index)) return defaultValue;
|
||||||
BdfList value = getOptionalList(index);
|
Object o = get(index);
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof BdfList) return (BdfList) o;
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfDictionary getDictionary(int index) throws FormatException {
|
public BdfDictionary getDictionary(int index) throws FormatException {
|
||||||
BdfDictionary value = getOptionalDictionary(index);
|
if (!isInRange(index)) throw new FormatException();
|
||||||
if (value == null) throw new FormatException();
|
Object o = get(index);
|
||||||
return value;
|
if (o instanceof BdfDictionary) return (BdfDictionary) o;
|
||||||
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -206,9 +207,10 @@ public final class BdfList extends ArrayList<Object> {
|
|||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
public BdfDictionary getDictionary(int index, BdfDictionary defaultValue)
|
public BdfDictionary getDictionary(int index, BdfDictionary defaultValue) {
|
||||||
throws FormatException {
|
if (!isInRange(index)) return defaultValue;
|
||||||
BdfDictionary value = getOptionalDictionary(index);
|
Object o = get(index);
|
||||||
return value == null ? defaultValue : value;
|
if (o instanceof BdfDictionary) return (BdfDictionary) o;
|
||||||
|
return defaultValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -32,12 +32,6 @@ public interface BdfReader {
|
|||||||
|
|
||||||
void skipLong() throws IOException;
|
void skipLong() throws IOException;
|
||||||
|
|
||||||
boolean hasInt() throws IOException;
|
|
||||||
|
|
||||||
int readInt() throws IOException;
|
|
||||||
|
|
||||||
void skipInt() throws IOException;
|
|
||||||
|
|
||||||
boolean hasDouble() throws IOException;
|
boolean hasDouble() throws IOException;
|
||||||
|
|
||||||
double readDouble() throws IOException;
|
double readDouble() throws IOException;
|
||||||
@@ -60,11 +54,23 @@ public interface BdfReader {
|
|||||||
|
|
||||||
BdfList readList() throws IOException;
|
BdfList readList() throws IOException;
|
||||||
|
|
||||||
|
void readListStart() throws IOException;
|
||||||
|
|
||||||
|
boolean hasListEnd() throws IOException;
|
||||||
|
|
||||||
|
void readListEnd() throws IOException;
|
||||||
|
|
||||||
void skipList() throws IOException;
|
void skipList() throws IOException;
|
||||||
|
|
||||||
boolean hasDictionary() throws IOException;
|
boolean hasDictionary() throws IOException;
|
||||||
|
|
||||||
BdfDictionary readDictionary() throws IOException;
|
BdfDictionary readDictionary() throws IOException;
|
||||||
|
|
||||||
|
void readDictionaryStart() throws IOException;
|
||||||
|
|
||||||
|
boolean hasDictionaryEnd() throws IOException;
|
||||||
|
|
||||||
|
void readDictionaryEnd() throws IOException;
|
||||||
|
|
||||||
void skipDictionary() throws IOException;
|
void skipDictionary() throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,8 +9,6 @@ public interface BdfReaderFactory {
|
|||||||
|
|
||||||
BdfReader createReader(InputStream in);
|
BdfReader createReader(InputStream in);
|
||||||
|
|
||||||
BdfReader createReader(InputStream in, boolean canonical);
|
|
||||||
|
|
||||||
BdfReader createReader(InputStream in, int nestedLimit,
|
BdfReader createReader(InputStream in, int nestedLimit,
|
||||||
int maxBufferSize, boolean canonical);
|
int maxBufferSize);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,5 +24,13 @@ public interface BdfWriter {
|
|||||||
|
|
||||||
void writeList(Collection<?> c) throws IOException;
|
void writeList(Collection<?> c) throws IOException;
|
||||||
|
|
||||||
|
void writeListStart() throws IOException;
|
||||||
|
|
||||||
|
void writeListEnd() throws IOException;
|
||||||
|
|
||||||
void writeDictionary(Map<?, ?> m) throws IOException;
|
void writeDictionary(Map<?, ?> m) throws IOException;
|
||||||
|
|
||||||
|
void writeDictionaryStart() throws IOException;
|
||||||
|
|
||||||
|
void writeDictionaryEnd() throws IOException;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.bramble.api.mailbox;
|
package org.briarproject.bramble.api.mailbox;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
||||||
@@ -35,16 +34,6 @@ public interface MailboxManager {
|
|||||||
*/
|
*/
|
||||||
MailboxPairingTask startPairingTask(String qrCodePayload);
|
MailboxPairingTask startPairingTask(String qrCodePayload);
|
||||||
|
|
||||||
/**
|
|
||||||
* Takes a textual QR code representation in
|
|
||||||
* {@link org.briarproject.bramble.util.Base32} format and converts it
|
|
||||||
* into a qrCodePayload as expected by {@link #startPairingTask(String)}.
|
|
||||||
*
|
|
||||||
* @throws FormatException when the provided payload did not include a
|
|
||||||
* proper briar-mailbox:// link.
|
|
||||||
*/
|
|
||||||
String convertBase32Payload(String base32Payload) throws FormatException;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Can be used by the UI to test the mailbox connection.
|
* Can be used by the UI to test the mailbox connection.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -14,7 +14,6 @@ import java.util.regex.Pattern;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import static java.nio.charset.CodingErrorAction.IGNORE;
|
import static java.nio.charset.CodingErrorAction.IGNORE;
|
||||||
import static java.nio.charset.CodingErrorAction.REPORT;
|
|
||||||
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
import static java.util.regex.Pattern.CASE_INSENSITIVE;
|
||||||
|
|
||||||
@SuppressWarnings("CharsetObjectCanBeUsed")
|
@SuppressWarnings("CharsetObjectCanBeUsed")
|
||||||
@@ -53,38 +52,26 @@ public class StringUtils {
|
|||||||
return s.getBytes(UTF_8);
|
return s.getBytes(UTF_8);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String fromUtf8(byte[] bytes) throws FormatException {
|
public static String fromUtf8(byte[] bytes) {
|
||||||
return fromUtf8(bytes, 0, bytes.length, true);
|
return fromUtf8(bytes, 0, bytes.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String fromUtf8(byte[] bytes, int off, int len)
|
public static String fromUtf8(byte[] bytes, int off, int len) {
|
||||||
throws FormatException {
|
|
||||||
return fromUtf8(bytes, off, len, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static String fromUtf8(byte[] bytes, int off, int len,
|
|
||||||
boolean strict) throws FormatException {
|
|
||||||
CharsetDecoder decoder = UTF_8.newDecoder();
|
CharsetDecoder decoder = UTF_8.newDecoder();
|
||||||
decoder.onMalformedInput(strict ? REPORT : IGNORE);
|
decoder.onMalformedInput(IGNORE);
|
||||||
decoder.onUnmappableCharacter(strict ? REPORT : IGNORE);
|
decoder.onUnmappableCharacter(IGNORE);
|
||||||
ByteBuffer buffer = ByteBuffer.wrap(bytes, off, len);
|
ByteBuffer buffer = ByteBuffer.wrap(bytes, off, len);
|
||||||
try {
|
try {
|
||||||
return decoder.decode(buffer).toString();
|
return decoder.decode(buffer).toString();
|
||||||
} catch (CharacterCodingException e) {
|
} catch (CharacterCodingException e) {
|
||||||
throw new FormatException();
|
throw new AssertionError(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String truncateUtf8(String s, int maxUtf8Length) {
|
public static String truncateUtf8(String s, int maxUtf8Length) {
|
||||||
byte[] utf8 = toUtf8(s);
|
byte[] utf8 = toUtf8(s);
|
||||||
if (utf8.length <= maxUtf8Length) return s;
|
if (utf8.length <= maxUtf8Length) return s;
|
||||||
// Don't be strict when converting back, so that if we truncate a
|
return fromUtf8(utf8, 0, maxUtf8Length);
|
||||||
// multi-byte character the whole character gets dropped
|
|
||||||
try {
|
|
||||||
return fromUtf8(utf8, 0, maxUtf8Length, false);
|
|
||||||
} catch (FormatException e) {
|
|
||||||
throw new AssertionError(e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package org.briarproject.bramble.api.data;
|
package org.briarproject.bramble.api.data;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.Bytes;
|
import org.briarproject.bramble.api.Bytes;
|
||||||
import org.briarproject.bramble.api.FormatException;
|
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -9,12 +8,9 @@ import java.util.Collections;
|
|||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import static java.lang.Boolean.TRUE;
|
|
||||||
import static java.util.Collections.singletonMap;
|
|
||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
public class BdfDictionaryTest extends BrambleTestCase {
|
public class BdfDictionaryTest extends BrambleTestCase {
|
||||||
@@ -23,20 +19,20 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
public void testConstructors() {
|
public void testConstructors() {
|
||||||
assertEquals(Collections.<String, Object>emptyMap(),
|
assertEquals(Collections.<String, Object>emptyMap(),
|
||||||
new BdfDictionary());
|
new BdfDictionary());
|
||||||
assertEquals(singletonMap("foo", NULL_VALUE),
|
assertEquals(Collections.singletonMap("foo", NULL_VALUE),
|
||||||
new BdfDictionary(singletonMap("foo", NULL_VALUE)));
|
new BdfDictionary(Collections.singletonMap("foo", NULL_VALUE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFactoryMethod() {
|
public void testFactoryMethod() {
|
||||||
assertEquals(Collections.<String, Object>emptyMap(),
|
assertEquals(Collections.<String, Object>emptyMap(),
|
||||||
BdfDictionary.of());
|
BdfDictionary.of());
|
||||||
assertEquals(singletonMap("foo", NULL_VALUE),
|
assertEquals(Collections.singletonMap("foo", NULL_VALUE),
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)));
|
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLongPromotion() throws Exception {
|
public void testIntegerPromotion() throws Exception {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
d.put("foo", (byte) 1);
|
d.put("foo", (byte) 1);
|
||||||
d.put("bar", (short) 2);
|
d.put("bar", (short) 2);
|
||||||
@@ -48,33 +44,6 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
assertEquals(Long.valueOf(4), d.getLong("bam"));
|
assertEquals(Long.valueOf(4), d.getLong("bam"));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIntPromotionAndDemotion() throws Exception {
|
|
||||||
BdfDictionary d = new BdfDictionary();
|
|
||||||
d.put("foo", (byte) 1);
|
|
||||||
d.put("bar", (short) 2);
|
|
||||||
d.put("baz", 3);
|
|
||||||
d.put("bam", 4L);
|
|
||||||
assertEquals(Integer.valueOf(1), d.getInt("foo"));
|
|
||||||
assertEquals(Integer.valueOf(2), d.getInt("bar"));
|
|
||||||
assertEquals(Integer.valueOf(3), d.getInt("baz"));
|
|
||||||
assertEquals(Integer.valueOf(4), d.getInt("bam"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testIntUnderflow() throws Exception {
|
|
||||||
BdfDictionary d =
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", Integer.MIN_VALUE - 1L));
|
|
||||||
d.getInt("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testIntOverflow() throws Exception {
|
|
||||||
BdfDictionary d =
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", Integer.MAX_VALUE + 1L));
|
|
||||||
d.getInt("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFloatPromotion() throws Exception {
|
public void testFloatPromotion() throws Exception {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
@@ -98,7 +67,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testKeySetIteratorIsOrderedByKeys() {
|
public void testKeySetIteratorIsOrderedByKeys() throws Exception {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
d.put("a", 1);
|
d.put("a", 1);
|
||||||
d.put("d", 4);
|
d.put("d", 4);
|
||||||
@@ -117,7 +86,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testValuesIteratorIsOrderedByKeys() {
|
public void testValuesIteratorIsOrderedByKeys() throws Exception {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
d.put("a", 1);
|
d.put("a", 1);
|
||||||
d.put("d", 4);
|
d.put("d", 4);
|
||||||
@@ -136,7 +105,7 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testEntrySetIteratorIsOrderedByKeys() {
|
public void testEntrySetIteratorIsOrderedByKeys() throws Exception {
|
||||||
BdfDictionary d = new BdfDictionary();
|
BdfDictionary d = new BdfDictionary();
|
||||||
d.put("a", 1);
|
d.put("a", 1);
|
||||||
d.put("d", 4);
|
d.put("d", 4);
|
||||||
@@ -161,284 +130,4 @@ public class BdfDictionaryTest extends BrambleTestCase {
|
|||||||
assertEquals("d", e.getKey());
|
assertEquals("d", e.getKey());
|
||||||
assertEquals(4, e.getValue());
|
assertEquals(4, e.getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testMissingValueForBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfDictionary().getBoolean("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testMissingValueForLongThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfDictionary().getLong("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testMissingValueForIntThrowsFormatException() throws Exception {
|
|
||||||
new BdfDictionary().getInt("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testMissingValueForDoubleThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfDictionary().getDouble("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testMissingValueForStringThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfDictionary().getString("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testMissingValueForRawThrowsFormatException() throws Exception {
|
|
||||||
new BdfDictionary().getRaw("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testMissingValueForListThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfDictionary().getList("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testMissingValueForDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfDictionary().getDictionary("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getBoolean("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForLongThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getLong("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForIntThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getInt("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForDoubleThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getDouble("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForStringThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getString("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForRawThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getRaw("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForListThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getList("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", NULL_VALUE)).getDictionary("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOptionalMethodsReturnNullForMissingValue()
|
|
||||||
throws Exception {
|
|
||||||
testOptionalMethodsReturnNull(new BdfDictionary());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOptionalMethodsReturnNullForNullValue() throws Exception {
|
|
||||||
BdfDictionary d = BdfDictionary.of(new BdfEntry("foo", NULL_VALUE));
|
|
||||||
testOptionalMethodsReturnNull(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testOptionalMethodsReturnNull(BdfDictionary d)
|
|
||||||
throws Exception {
|
|
||||||
assertNull(d.getOptionalBoolean("foo"));
|
|
||||||
assertNull(d.getOptionalLong("foo"));
|
|
||||||
assertNull(d.getOptionalInt("foo"));
|
|
||||||
assertNull(d.getOptionalDouble("foo"));
|
|
||||||
assertNull(d.getOptionalString("foo"));
|
|
||||||
assertNull(d.getOptionalRaw("foo"));
|
|
||||||
assertNull(d.getOptionalList("foo"));
|
|
||||||
assertNull(d.getOptionalDictionary("foo"));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefaultMethodsReturnDefaultForMissingValue()
|
|
||||||
throws Exception {
|
|
||||||
testDefaultMethodsReturnDefault(new BdfDictionary());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefaultMethodsReturnDefaultForNullValue() throws Exception {
|
|
||||||
BdfDictionary d = BdfDictionary.of(new BdfEntry("foo", NULL_VALUE));
|
|
||||||
testDefaultMethodsReturnDefault(d);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void testDefaultMethodsReturnDefault(BdfDictionary d)
|
|
||||||
throws Exception {
|
|
||||||
assertEquals(TRUE, d.getBoolean("foo", TRUE));
|
|
||||||
assertEquals(Long.valueOf(123L), d.getLong("foo", 123L));
|
|
||||||
assertEquals(Integer.valueOf(123), d.getInt("foo", 123));
|
|
||||||
assertEquals(Double.valueOf(123D), d.getDouble("foo", 123D));
|
|
||||||
assertEquals("123", d.getString("foo", "123"));
|
|
||||||
byte[] defaultRaw = {1, 2, 3};
|
|
||||||
assertArrayEquals(defaultRaw, d.getRaw("foo", defaultRaw));
|
|
||||||
BdfList defaultList = BdfList.of(1, 2, 3);
|
|
||||||
assertEquals(defaultList, d.getList("foo", defaultList));
|
|
||||||
BdfDictionary defaultDict = BdfDictionary.of(new BdfEntry("123", 123));
|
|
||||||
assertEquals(defaultDict, d.getDictionary("foo", defaultDict));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getBoolean("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalBoolean("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getBoolean("foo", true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForLongThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 1.23)).getLong("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalLongThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 1.23)).getOptionalLong("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultLongThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 1.23)).getLong("foo", 1L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForIntThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 1.23)).getInt("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 1.23)).getOptionalInt("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 1.23)).getInt("foo", 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDoubleThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getDouble("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalDoubleThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalDouble("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultDoubleThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getDouble("foo", 1D);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForStringThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getString("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalStringThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalString("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultStringThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getString("foo", "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForRawThrowsFormatException() throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getRaw("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalRawThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalRaw("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultRawThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getRaw("foo", new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForListThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getList("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalListThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalList("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultListThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getList("foo",
|
|
||||||
new BdfList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getDictionary("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getOptionalDictionary("foo");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfDictionary.of(new BdfEntry("foo", 123)).getDictionary("foo",
|
|
||||||
new BdfDictionary());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,31 +5,31 @@ import org.briarproject.bramble.api.FormatException;
|
|||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static java.lang.Boolean.TRUE;
|
import java.util.Arrays;
|
||||||
import static java.util.Arrays.asList;
|
import java.util.Collections;
|
||||||
import static java.util.Collections.emptyList;
|
|
||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
import static org.junit.Assert.assertArrayEquals;
|
import static org.junit.Assert.assertArrayEquals;
|
||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNull;
|
|
||||||
|
|
||||||
public class BdfListTest extends BrambleTestCase {
|
public class BdfListTest extends BrambleTestCase {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testConstructors() {
|
public void testConstructors() {
|
||||||
assertEquals(emptyList(), new BdfList());
|
assertEquals(Collections.emptyList(), new BdfList());
|
||||||
assertEquals(asList(1, 2, NULL_VALUE),
|
assertEquals(Arrays.asList(1, 2, NULL_VALUE),
|
||||||
new BdfList(asList(1, 2, NULL_VALUE)));
|
new BdfList(Arrays.asList(1, 2, NULL_VALUE)));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFactoryMethod() {
|
public void testFactoryMethod() {
|
||||||
assertEquals(emptyList(), BdfList.of());
|
assertEquals(Collections.emptyList(), BdfList.of());
|
||||||
assertEquals(asList(1, 2, NULL_VALUE), BdfList.of(1, 2, NULL_VALUE));
|
assertEquals(Arrays.asList(1, 2, NULL_VALUE),
|
||||||
|
BdfList.of(1, 2, NULL_VALUE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testLongPromotion() throws Exception {
|
public void testIntegerPromotion() throws Exception {
|
||||||
BdfList list = new BdfList();
|
BdfList list = new BdfList();
|
||||||
list.add((byte) 1);
|
list.add((byte) 1);
|
||||||
list.add((short) 2);
|
list.add((short) 2);
|
||||||
@@ -41,31 +41,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
assertEquals(Long.valueOf(4), list.getLong(3));
|
assertEquals(Long.valueOf(4), list.getLong(3));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testIntPromotionAndDemotion() throws Exception {
|
|
||||||
BdfList list = new BdfList();
|
|
||||||
list.add((byte) 1);
|
|
||||||
list.add((short) 2);
|
|
||||||
list.add(3);
|
|
||||||
list.add(4L);
|
|
||||||
assertEquals(Integer.valueOf(1), list.getInt(0));
|
|
||||||
assertEquals(Integer.valueOf(2), list.getInt(1));
|
|
||||||
assertEquals(Integer.valueOf(3), list.getInt(2));
|
|
||||||
assertEquals(Integer.valueOf(4), list.getInt(3));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testIntUnderflow() throws Exception {
|
|
||||||
BdfList list = BdfList.of(Integer.MIN_VALUE - 1L);
|
|
||||||
list.getInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testIntOverflow() throws Exception {
|
|
||||||
BdfList list = BdfList.of(Integer.MAX_VALUE + 1L);
|
|
||||||
list.getInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFloatPromotion() throws Exception {
|
public void testFloatPromotion() throws Exception {
|
||||||
BdfList list = new BdfList();
|
BdfList list = new BdfList();
|
||||||
@@ -88,6 +63,61 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
assertArrayEquals(new byte[123], second);
|
assertArrayEquals(new byte[123], second);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public void testIndexOutOfBoundsReturnsDefaultValue() throws Exception {
|
||||||
|
BdfList list = BdfList.of(1, 2, 3);
|
||||||
|
boolean defaultBoolean = true;
|
||||||
|
assertEquals(defaultBoolean, list.getBoolean(-1, defaultBoolean));
|
||||||
|
assertEquals(defaultBoolean, list.getBoolean(3, defaultBoolean));
|
||||||
|
Long defaultLong = 123L;
|
||||||
|
assertEquals(defaultLong, list.getLong(-1, defaultLong));
|
||||||
|
assertEquals(defaultLong, list.getLong(3, defaultLong));
|
||||||
|
Double defaultDouble = 1.23;
|
||||||
|
assertEquals(defaultDouble, list.getDouble(-1, defaultDouble));
|
||||||
|
assertEquals(defaultDouble, list.getDouble(3, defaultDouble));
|
||||||
|
String defaultString = "123";
|
||||||
|
assertEquals(defaultString, list.getString(-1, defaultString));
|
||||||
|
assertEquals(defaultString, list.getString(3, defaultString));
|
||||||
|
byte[] defaultBytes = new byte[] {1, 2, 3};
|
||||||
|
assertArrayEquals(defaultBytes, list.getRaw(-1, defaultBytes));
|
||||||
|
assertArrayEquals(defaultBytes, list.getRaw(3, defaultBytes));
|
||||||
|
BdfList defaultList = BdfList.of(1, 2, 3);
|
||||||
|
assertEquals(defaultList, list.getList(-1, defaultList));
|
||||||
|
assertEquals(defaultList, list.getList(3, defaultList));
|
||||||
|
BdfDictionary defaultDict = BdfDictionary.of(
|
||||||
|
new BdfEntry("1", 1),
|
||||||
|
new BdfEntry("2", 2),
|
||||||
|
new BdfEntry("3", 3)
|
||||||
|
);
|
||||||
|
assertEquals(defaultDict, list.getDictionary(-1, defaultDict));
|
||||||
|
assertEquals(defaultDict, list.getDictionary(3, defaultDict));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@SuppressWarnings("ConstantConditions")
|
||||||
|
public void testWrongTypeReturnsDefaultValue() throws Exception {
|
||||||
|
BdfList list = BdfList.of(1, 2, 3, true);
|
||||||
|
boolean defaultBoolean = true;
|
||||||
|
assertEquals(defaultBoolean, list.getBoolean(0, defaultBoolean));
|
||||||
|
Long defaultLong = 123L;
|
||||||
|
assertEquals(defaultLong, list.getLong(3, defaultLong));
|
||||||
|
Double defaultDouble = 1.23;
|
||||||
|
assertEquals(defaultDouble, list.getDouble(0, defaultDouble));
|
||||||
|
String defaultString = "123";
|
||||||
|
assertEquals(defaultString, list.getString(0, defaultString));
|
||||||
|
byte[] defaultBytes = new byte[] {1, 2, 3};
|
||||||
|
assertArrayEquals(defaultBytes, list.getRaw(0, defaultBytes));
|
||||||
|
BdfList defaultList = BdfList.of(1, 2, 3);
|
||||||
|
assertEquals(defaultList, list.getList(0, defaultList));
|
||||||
|
BdfDictionary defaultDict = BdfDictionary.of(
|
||||||
|
new BdfEntry("1", 1),
|
||||||
|
new BdfEntry("2", 2),
|
||||||
|
new BdfEntry("3", 3)
|
||||||
|
);
|
||||||
|
assertEquals(defaultDict, list.getDictionary(0, defaultDict));
|
||||||
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNegativeIndexForBooleanThrowsFormatException()
|
public void testNegativeIndexForBooleanThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -100,12 +130,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalBoolean(-1);
|
new BdfList().getOptionalBoolean(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForDefaultBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getBoolean(-1, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNegativeIndexForLongThrowsFormatException()
|
public void testNegativeIndexForLongThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -118,30 +142,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalLong(-1);
|
new BdfList().getOptionalLong(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForDefaultLongThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getLong(-1, 1L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getInt(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForOptionalIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getOptionalInt(-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForDefaultIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getInt(-1, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNegativeIndexForDoubleThrowsFormatException()
|
public void testNegativeIndexForDoubleThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -154,12 +154,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalDouble(-1);
|
new BdfList().getOptionalDouble(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForDefaultDoubleThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getDouble(-1, 1D);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNegativeIndexForStringThrowsFormatException()
|
public void testNegativeIndexForStringThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -172,12 +166,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalString(-1);
|
new BdfList().getOptionalString(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForDefaultStringThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getString(-1, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNegativeIndexForRawThrowsFormatException()
|
public void testNegativeIndexForRawThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -190,12 +178,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalRaw(-1);
|
new BdfList().getOptionalRaw(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForDefaultRawThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getRaw(-1, new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNegativeIndexForListThrowsFormatException()
|
public void testNegativeIndexForListThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -208,11 +190,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalList(-1);
|
new BdfList().getOptionalList(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForDefaultListThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getList(-1, new BdfList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNegativeIndexForDictionaryThrowsFormatException()
|
public void testNegativeIndexForDictionaryThrowsFormatException()
|
||||||
@@ -226,12 +203,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalDictionary(-1);
|
new BdfList().getOptionalDictionary(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNegativeIndexForDefaultDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getDictionary(-1, new BdfDictionary());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testTooLargeIndexForBooleanThrowsFormatException()
|
public void testTooLargeIndexForBooleanThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -244,12 +215,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalBoolean(0);
|
new BdfList().getOptionalBoolean(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForDefaultBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getBoolean(0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testTooLargeIndexForLongThrowsFormatException()
|
public void testTooLargeIndexForLongThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -262,30 +227,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalLong(0);
|
new BdfList().getOptionalLong(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForDefaultLongThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getLong(0, 1L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForOptionalIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getOptionalInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForDefaultIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getInt(0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testTooLargeIndexForDoubleThrowsFormatException()
|
public void testTooLargeIndexForDoubleThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -298,12 +239,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalDouble(0);
|
new BdfList().getOptionalDouble(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForDefaultDoubleThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getDouble(0, 1D);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testTooLargeIndexForStringThrowsFormatException()
|
public void testTooLargeIndexForStringThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -316,12 +251,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalString(0);
|
new BdfList().getOptionalString(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForDefaultStringThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getString(0, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testTooLargeIndexForRawThrowsFormatException()
|
public void testTooLargeIndexForRawThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -334,12 +263,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalRaw(0);
|
new BdfList().getOptionalRaw(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForDefaultRawThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getRaw(0, new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testTooLargeIndexForListThrowsFormatException()
|
public void testTooLargeIndexForListThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -352,11 +275,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
new BdfList().getOptionalList(0);
|
new BdfList().getOptionalList(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForDefaultListThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getList(0, new BdfList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testTooLargeIndexForDictionaryThrowsFormatException()
|
public void testTooLargeIndexForDictionaryThrowsFormatException()
|
||||||
@@ -369,13 +287,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
new BdfList().getOptionalDictionary(0);
|
new BdfList().getOptionalDictionary(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testTooLargeIndexForDefaultDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
new BdfList().getDictionary(0, new BdfDictionary());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testWrongTypeForBooleanThrowsFormatException()
|
public void testWrongTypeForBooleanThrowsFormatException()
|
||||||
throws Exception {
|
throws Exception {
|
||||||
@@ -388,12 +299,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
BdfList.of(123).getOptionalBoolean(0);
|
BdfList.of(123).getOptionalBoolean(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(123).getBoolean(0, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testWrongTypeForLongThrowsFormatException() throws Exception {
|
public void testWrongTypeForLongThrowsFormatException() throws Exception {
|
||||||
BdfList.of(1.23).getLong(0);
|
BdfList.of(1.23).getLong(0);
|
||||||
@@ -405,29 +310,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
BdfList.of(1.23).getOptionalLong(0);
|
BdfList.of(1.23).getOptionalLong(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultLongThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(1.23).getLong(0, 1L);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForIntThrowsFormatException() throws Exception {
|
|
||||||
BdfList.of(1.23).getInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForOptionalIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(1.23).getOptionalInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultIntThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(1.23).getInt(0, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testWrongTypeForDoubleThrowsFormatException() throws Exception {
|
public void testWrongTypeForDoubleThrowsFormatException() throws Exception {
|
||||||
BdfList.of(123).getDouble(0);
|
BdfList.of(123).getDouble(0);
|
||||||
@@ -439,12 +321,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
BdfList.of(123).getOptionalDouble(0);
|
BdfList.of(123).getOptionalDouble(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultDoubleThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(123).getDouble(0, 1D);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testWrongTypeForStringThrowsFormatException() throws Exception {
|
public void testWrongTypeForStringThrowsFormatException() throws Exception {
|
||||||
BdfList.of(123).getString(0);
|
BdfList.of(123).getString(0);
|
||||||
@@ -456,12 +332,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
BdfList.of(123).getOptionalString(0);
|
BdfList.of(123).getOptionalString(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultStringThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(123).getString(0, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testWrongTypeForRawThrowsFormatException() throws Exception {
|
public void testWrongTypeForRawThrowsFormatException() throws Exception {
|
||||||
BdfList.of(123).getRaw(0);
|
BdfList.of(123).getRaw(0);
|
||||||
@@ -473,12 +343,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
BdfList.of(123).getOptionalRaw(0);
|
BdfList.of(123).getOptionalRaw(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultRawThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(123).getRaw(0, new byte[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testWrongTypeForListThrowsFormatException() throws Exception {
|
public void testWrongTypeForListThrowsFormatException() throws Exception {
|
||||||
BdfList.of(123).getList(0);
|
BdfList.of(123).getList(0);
|
||||||
@@ -490,11 +354,6 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
BdfList.of(123).getOptionalList(0);
|
BdfList.of(123).getOptionalList(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultListThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(123).getList(0, new BdfList());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testWrongTypeForDictionaryThrowsFormatException()
|
public void testWrongTypeForDictionaryThrowsFormatException()
|
||||||
@@ -507,81 +366,4 @@ public class BdfListTest extends BrambleTestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
BdfList.of(123).getOptionalDictionary(0);
|
BdfList.of(123).getOptionalDictionary(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testWrongTypeForDefaultDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(123).getDictionary(0, new BdfDictionary());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForBooleanThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(NULL_VALUE).getBoolean(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForLongThrowsFormatException() throws Exception {
|
|
||||||
BdfList.of(NULL_VALUE).getLong(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForIntThrowsFormatException() throws Exception {
|
|
||||||
BdfList.of(NULL_VALUE).getInt(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForDoubleThrowsFormatException() throws Exception {
|
|
||||||
BdfList.of(NULL_VALUE).getDouble(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForStringThrowsFormatException() throws Exception {
|
|
||||||
BdfList.of(NULL_VALUE).getString(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForRawThrowsFormatException() throws Exception {
|
|
||||||
BdfList.of(NULL_VALUE).getRaw(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForListThrowsFormatException() throws Exception {
|
|
||||||
BdfList.of(NULL_VALUE).getList(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testNullValueForDictionaryThrowsFormatException()
|
|
||||||
throws Exception {
|
|
||||||
BdfList.of(NULL_VALUE).getDictionary(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testOptionalMethodsReturnNullForNullValue() throws Exception {
|
|
||||||
BdfList list = BdfList.of(NULL_VALUE);
|
|
||||||
assertNull(list.getOptionalBoolean(0));
|
|
||||||
assertNull(list.getOptionalLong(0));
|
|
||||||
assertNull(list.getOptionalInt(0));
|
|
||||||
assertNull(list.getOptionalDouble(0));
|
|
||||||
assertNull(list.getOptionalString(0));
|
|
||||||
assertNull(list.getOptionalRaw(0));
|
|
||||||
assertNull(list.getOptionalList(0));
|
|
||||||
assertNull(list.getOptionalDictionary(0));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testDefaultMethodsReturnDefaultForNullValue() throws Exception {
|
|
||||||
BdfList list = BdfList.of(NULL_VALUE);
|
|
||||||
assertEquals(TRUE, list.getBoolean(0, TRUE));
|
|
||||||
assertEquals(Long.valueOf(123L), list.getLong(0, 123L));
|
|
||||||
assertEquals(Integer.valueOf(123), list.getInt(0, 123));
|
|
||||||
assertEquals(Double.valueOf(123D), list.getDouble(0, 123D));
|
|
||||||
assertEquals("123", list.getString(0, "123"));
|
|
||||||
byte[] defaultRaw = {1, 2, 3};
|
|
||||||
assertArrayEquals(defaultRaw, list.getRaw(0, defaultRaw));
|
|
||||||
BdfList defaultList = BdfList.of(1, 2, 3);
|
|
||||||
assertEquals(defaultList, list.getList(0, defaultList));
|
|
||||||
BdfDictionary defaultDict = BdfDictionary.of(new BdfEntry("123", 123));
|
|
||||||
assertEquals(defaultDict, list.getDictionary(0, defaultDict));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -155,13 +155,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
@Override
|
@Override
|
||||||
public BdfList getMessageAsList(Transaction txn, MessageId m)
|
public BdfList getMessageAsList(Transaction txn, MessageId m)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
return getMessageAsList(txn, m, true);
|
return toList(db.getMessage(txn, m).getBody());
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BdfList getMessageAsList(Transaction txn, MessageId m,
|
|
||||||
boolean canonical) throws DbException, FormatException {
|
|
||||||
return toList(db.getMessage(txn, m), canonical);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -319,13 +313,8 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BdfList toList(byte[] b, int off, int len) throws FormatException {
|
public BdfList toList(byte[] b, int off, int len) throws FormatException {
|
||||||
return toList(b, off, len, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
private BdfList toList(byte[] b, int off, int len, boolean canonical)
|
|
||||||
throws FormatException {
|
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(b, off, len);
|
ByteArrayInputStream in = new ByteArrayInputStream(b, off, len);
|
||||||
BdfReader reader = bdfReaderFactory.createReader(in, canonical);
|
BdfReader reader = bdfReaderFactory.createReader(in);
|
||||||
try {
|
try {
|
||||||
BdfList list = reader.readList();
|
BdfList list = reader.readList();
|
||||||
if (!reader.eof()) throw new FormatException();
|
if (!reader.eof()) throw new FormatException();
|
||||||
@@ -339,7 +328,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BdfList toList(byte[] b) throws FormatException {
|
public BdfList toList(byte[] b) throws FormatException {
|
||||||
return toList(b, 0, b.length, true);
|
return toList(b, 0, b.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -347,12 +336,6 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
return toList(m.getBody());
|
return toList(m.getBody());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public BdfList toList(Message m, boolean canonical) throws FormatException {
|
|
||||||
byte[] b = m.getBody();
|
|
||||||
return toList(b, 0, b.length, canonical);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BdfList toList(Author a) {
|
public BdfList toList(Author a) {
|
||||||
return BdfList.of(a.getFormatVersion(), a.getName(), a.getPublicKey());
|
return BdfList.of(a.getFormatVersion(), a.getName(), a.getPublicKey());
|
||||||
@@ -378,7 +361,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
public Author parseAndValidateAuthor(BdfList author)
|
public Author parseAndValidateAuthor(BdfList author)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
checkSize(author, 3);
|
checkSize(author, 3);
|
||||||
int formatVersion = author.getInt(0);
|
int formatVersion = author.getLong(0).intValue();
|
||||||
if (formatVersion != FORMAT_VERSION) throw new FormatException();
|
if (formatVersion != FORMAT_VERSION) throw new FormatException();
|
||||||
String name = author.getString(1);
|
String name = author.getString(1);
|
||||||
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
|
checkLength(name, 1, MAX_AUTHOR_NAME_LENGTH);
|
||||||
@@ -489,7 +472,8 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
if (element.size() != 2) {
|
if (element.size() != 2) {
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
list.add(new MailboxVersion(element.getInt(0), element.getInt(1)));
|
list.add(new MailboxVersion(element.getLong(0).intValue(),
|
||||||
|
element.getLong(1).intValue()));
|
||||||
}
|
}
|
||||||
// Sort the list of versions for easier comparison
|
// Sort the list of versions for easier comparison
|
||||||
sort(list);
|
sort(list);
|
||||||
@@ -502,7 +486,7 @@ class ClientHelperImpl implements ClientHelper {
|
|||||||
try {
|
try {
|
||||||
BdfDictionary meta =
|
BdfDictionary meta =
|
||||||
getGroupMetadataAsDictionary(txn, contactGroupId);
|
getGroupMetadataAsDictionary(txn, contactGroupId);
|
||||||
return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID));
|
return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue());
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e); // Invalid group metadata
|
throw new DbException(e); // Invalid group metadata
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,18 +18,12 @@ class BdfReaderFactoryImpl implements BdfReaderFactory {
|
|||||||
@Override
|
@Override
|
||||||
public BdfReader createReader(InputStream in) {
|
public BdfReader createReader(InputStream in) {
|
||||||
return new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
return new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
||||||
DEFAULT_MAX_BUFFER_SIZE, true);
|
DEFAULT_MAX_BUFFER_SIZE);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public BdfReader createReader(InputStream in, boolean canonical) {
|
|
||||||
return new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
|
||||||
DEFAULT_MAX_BUFFER_SIZE, canonical);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BdfReader createReader(InputStream in, int nestedLimit,
|
public BdfReader createReader(InputStream in, int nestedLimit,
|
||||||
int maxBufferSize, boolean canonical) {
|
int maxBufferSize) {
|
||||||
return new BdfReaderImpl(in, nestedLimit, maxBufferSize, canonical);
|
return new BdfReaderImpl(in, nestedLimit, maxBufferSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -33,24 +33,21 @@ import static org.briarproject.bramble.util.StringUtils.fromUtf8;
|
|||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
final class BdfReaderImpl implements BdfReader {
|
class BdfReaderImpl implements BdfReader {
|
||||||
|
|
||||||
private static final byte[] EMPTY_BUFFER = new byte[0];
|
private static final byte[] EMPTY_BUFFER = new byte[0];
|
||||||
|
|
||||||
private final InputStream in;
|
private final InputStream in;
|
||||||
private final int nestedLimit, maxBufferSize;
|
private final int nestedLimit, maxBufferSize;
|
||||||
private final boolean canonical;
|
|
||||||
|
|
||||||
private boolean hasLookahead = false, eof = false;
|
private boolean hasLookahead = false, eof = false;
|
||||||
private byte next;
|
private byte next;
|
||||||
private byte[] buf = new byte[8];
|
private byte[] buf = new byte[8];
|
||||||
|
|
||||||
BdfReaderImpl(InputStream in, int nestedLimit, int maxBufferSize,
|
BdfReaderImpl(InputStream in, int nestedLimit, int maxBufferSize) {
|
||||||
boolean canonical) {
|
|
||||||
this.in = in;
|
this.in = in;
|
||||||
this.nestedLimit = nestedLimit;
|
this.nestedLimit = nestedLimit;
|
||||||
this.maxBufferSize = maxBufferSize;
|
this.maxBufferSize = maxBufferSize;
|
||||||
this.canonical = canonical;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void readLookahead() throws IOException {
|
private void readLookahead() throws IOException {
|
||||||
@@ -191,22 +188,13 @@ final class BdfReaderImpl implements BdfReader {
|
|||||||
|
|
||||||
private short readInt16() throws IOException {
|
private short readInt16() throws IOException {
|
||||||
readIntoBuffer(2);
|
readIntoBuffer(2);
|
||||||
short value = (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF));
|
return (short) (((buf[0] & 0xFF) << 8) + (buf[1] & 0xFF));
|
||||||
if (canonical && value >= Byte.MIN_VALUE && value <= Byte.MAX_VALUE) {
|
|
||||||
// Value could have been encoded as an INT_8
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int readInt32() throws IOException {
|
private int readInt32() throws IOException {
|
||||||
readIntoBuffer(4);
|
readIntoBuffer(4);
|
||||||
int value = 0;
|
int value = 0;
|
||||||
for (int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8);
|
for (int i = 0; i < 4; i++) value |= (buf[i] & 0xFF) << (24 - i * 8);
|
||||||
if (canonical && value >= Short.MIN_VALUE && value <= Short.MAX_VALUE) {
|
|
||||||
// Value could have been encoded as an INT_16
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,11 +202,6 @@ final class BdfReaderImpl implements BdfReader {
|
|||||||
readIntoBuffer(8);
|
readIntoBuffer(8);
|
||||||
long value = 0;
|
long value = 0;
|
||||||
for (int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
|
for (int i = 0; i < 8; i++) value |= (buf[i] & 0xFFL) << (56 - i * 8);
|
||||||
if (canonical && value >= Integer.MIN_VALUE &&
|
|
||||||
value <= Integer.MAX_VALUE) {
|
|
||||||
// Value could have been encoded as an INT_32
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,31 +215,6 @@ final class BdfReaderImpl implements BdfReader {
|
|||||||
hasLookahead = false;
|
hasLookahead = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean hasInt() throws IOException {
|
|
||||||
if (!hasLookahead) readLookahead();
|
|
||||||
if (eof) return false;
|
|
||||||
return next == INT_8 || next == INT_16 || next == INT_32;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int readInt() throws IOException {
|
|
||||||
if (!hasInt()) throw new FormatException();
|
|
||||||
hasLookahead = false;
|
|
||||||
if (next == INT_8) return readInt8();
|
|
||||||
if (next == INT_16) return readInt16();
|
|
||||||
return readInt32();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void skipInt() throws IOException {
|
|
||||||
if (!hasInt()) throw new FormatException();
|
|
||||||
if (next == INT_8) skip(1);
|
|
||||||
else if (next == INT_16) skip(2);
|
|
||||||
else skip(4);
|
|
||||||
hasLookahead = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean hasDouble() throws IOException {
|
public boolean hasDouble() throws IOException {
|
||||||
if (!hasLookahead) readLookahead();
|
if (!hasLookahead) readLookahead();
|
||||||
@@ -365,19 +323,35 @@ final class BdfReaderImpl implements BdfReader {
|
|||||||
private BdfList readList(int level) throws IOException {
|
private BdfList readList(int level) throws IOException {
|
||||||
if (!hasList()) throw new FormatException();
|
if (!hasList()) throw new FormatException();
|
||||||
if (level > nestedLimit) throw new FormatException();
|
if (level > nestedLimit) throw new FormatException();
|
||||||
hasLookahead = false;
|
|
||||||
BdfList list = new BdfList();
|
BdfList list = new BdfList();
|
||||||
while (!hasEnd()) list.add(readObject(level + 1));
|
readListStart();
|
||||||
readEnd();
|
while (!hasListEnd()) list.add(readObject(level + 1));
|
||||||
|
readListEnd();
|
||||||
return list;
|
return list;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readListStart() throws IOException {
|
||||||
|
if (!hasList()) throw new FormatException();
|
||||||
|
hasLookahead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasListEnd() throws IOException {
|
||||||
|
return hasEnd();
|
||||||
|
}
|
||||||
|
|
||||||
private boolean hasEnd() throws IOException {
|
private boolean hasEnd() throws IOException {
|
||||||
if (!hasLookahead) readLookahead();
|
if (!hasLookahead) readLookahead();
|
||||||
if (eof) return false;
|
if (eof) return false;
|
||||||
return next == END;
|
return next == END;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readListEnd() throws IOException {
|
||||||
|
readEnd();
|
||||||
|
}
|
||||||
|
|
||||||
private void readEnd() throws IOException {
|
private void readEnd() throws IOException {
|
||||||
if (!hasEnd()) throw new FormatException();
|
if (!hasEnd()) throw new FormatException();
|
||||||
hasLookahead = false;
|
hasLookahead = false;
|
||||||
@@ -387,7 +361,7 @@ final class BdfReaderImpl implements BdfReader {
|
|||||||
public void skipList() throws IOException {
|
public void skipList() throws IOException {
|
||||||
if (!hasList()) throw new FormatException();
|
if (!hasList()) throw new FormatException();
|
||||||
hasLookahead = false;
|
hasLookahead = false;
|
||||||
while (!hasEnd()) skipObject();
|
while (!hasListEnd()) skipObject();
|
||||||
hasLookahead = false;
|
hasLookahead = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -406,27 +380,35 @@ final class BdfReaderImpl implements BdfReader {
|
|||||||
private BdfDictionary readDictionary(int level) throws IOException {
|
private BdfDictionary readDictionary(int level) throws IOException {
|
||||||
if (!hasDictionary()) throw new FormatException();
|
if (!hasDictionary()) throw new FormatException();
|
||||||
if (level > nestedLimit) throw new FormatException();
|
if (level > nestedLimit) throw new FormatException();
|
||||||
hasLookahead = false;
|
|
||||||
BdfDictionary dictionary = new BdfDictionary();
|
BdfDictionary dictionary = new BdfDictionary();
|
||||||
String prevKey = null;
|
readDictionaryStart();
|
||||||
while (!hasEnd()) {
|
while (!hasDictionaryEnd())
|
||||||
String key = readString();
|
dictionary.put(readString(), readObject(level + 1));
|
||||||
if (canonical && prevKey != null && key.compareTo(prevKey) <= 0) {
|
readDictionaryEnd();
|
||||||
// Keys not unique and sorted
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
dictionary.put(key, readObject(level + 1));
|
|
||||||
prevKey = key;
|
|
||||||
}
|
|
||||||
readEnd();
|
|
||||||
return dictionary;
|
return dictionary;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readDictionaryStart() throws IOException {
|
||||||
|
if (!hasDictionary()) throw new FormatException();
|
||||||
|
hasLookahead = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasDictionaryEnd() throws IOException {
|
||||||
|
return hasEnd();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void readDictionaryEnd() throws IOException {
|
||||||
|
readEnd();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void skipDictionary() throws IOException {
|
public void skipDictionary() throws IOException {
|
||||||
if (!hasDictionary()) throw new FormatException();
|
if (!hasDictionary()) throw new FormatException();
|
||||||
hasLookahead = false;
|
hasLookahead = false;
|
||||||
while (!hasEnd()) {
|
while (!hasDictionaryEnd()) {
|
||||||
skipString();
|
skipString();
|
||||||
skipObject();
|
skipObject();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,13 +2,11 @@ package org.briarproject.bramble.data;
|
|||||||
|
|
||||||
import org.briarproject.bramble.api.Bytes;
|
import org.briarproject.bramble.api.Bytes;
|
||||||
import org.briarproject.bramble.api.FormatException;
|
import org.briarproject.bramble.api.FormatException;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
|
||||||
import org.briarproject.bramble.api.data.BdfWriter;
|
import org.briarproject.bramble.api.data.BdfWriter;
|
||||||
import org.briarproject.nullsafety.NotNullByDefault;
|
import org.briarproject.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
@@ -17,7 +15,6 @@ import java.util.Map.Entry;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.NotThreadSafe;
|
import javax.annotation.concurrent.NotThreadSafe;
|
||||||
|
|
||||||
import static java.util.Collections.sort;
|
|
||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
import static org.briarproject.bramble.data.Types.DICTIONARY;
|
import static org.briarproject.bramble.data.Types.DICTIONARY;
|
||||||
import static org.briarproject.bramble.data.Types.END;
|
import static org.briarproject.bramble.data.Types.END;
|
||||||
@@ -36,11 +33,10 @@ import static org.briarproject.bramble.data.Types.STRING_16;
|
|||||||
import static org.briarproject.bramble.data.Types.STRING_32;
|
import static org.briarproject.bramble.data.Types.STRING_32;
|
||||||
import static org.briarproject.bramble.data.Types.STRING_8;
|
import static org.briarproject.bramble.data.Types.STRING_8;
|
||||||
import static org.briarproject.bramble.data.Types.TRUE;
|
import static org.briarproject.bramble.data.Types.TRUE;
|
||||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
|
||||||
|
|
||||||
@NotThreadSafe
|
@NotThreadSafe
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
final class BdfWriterImpl implements BdfWriter {
|
class BdfWriterImpl implements BdfWriter {
|
||||||
|
|
||||||
private final OutputStream out;
|
private final OutputStream out;
|
||||||
|
|
||||||
@@ -117,7 +113,7 @@ final class BdfWriterImpl implements BdfWriter {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeString(String s) throws IOException {
|
public void writeString(String s) throws IOException {
|
||||||
byte[] b = s.getBytes(UTF_8);
|
byte[] b = s.getBytes("UTF-8");
|
||||||
if (b.length <= Byte.MAX_VALUE) {
|
if (b.length <= Byte.MAX_VALUE) {
|
||||||
out.write(STRING_8);
|
out.write(STRING_8);
|
||||||
out.write((byte) b.length);
|
out.write((byte) b.length);
|
||||||
@@ -165,33 +161,39 @@ final class BdfWriterImpl implements BdfWriter {
|
|||||||
else if (o instanceof String) writeString((String) o);
|
else if (o instanceof String) writeString((String) o);
|
||||||
else if (o instanceof byte[]) writeRaw((byte[]) o);
|
else if (o instanceof byte[]) writeRaw((byte[]) o);
|
||||||
else if (o instanceof Bytes) writeRaw(((Bytes) o).getBytes());
|
else if (o instanceof Bytes) writeRaw(((Bytes) o).getBytes());
|
||||||
else if (o instanceof List) writeList((List<?>) o);
|
else if (o instanceof List) writeList((List) o);
|
||||||
else if (o instanceof Map) writeDictionary((Map<?, ?>) o);
|
else if (o instanceof Map) writeDictionary((Map) o);
|
||||||
else throw new FormatException();
|
else throw new FormatException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeListStart() throws IOException {
|
||||||
|
out.write(LIST);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeListEnd() throws IOException {
|
||||||
|
out.write(END);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void writeDictionary(Map<?, ?> m) throws IOException {
|
public void writeDictionary(Map<?, ?> m) throws IOException {
|
||||||
out.write(DICTIONARY);
|
out.write(DICTIONARY);
|
||||||
if (m instanceof BdfDictionary) {
|
for (Entry<?, ?> e : m.entrySet()) {
|
||||||
// Entries are already sorted and keys are known to be strings
|
if (!(e.getKey() instanceof String)) throw new FormatException();
|
||||||
for (Entry<String, Object> e : ((BdfDictionary) m).entrySet()) {
|
writeString((String) e.getKey());
|
||||||
writeString(e.getKey());
|
writeObject(e.getValue());
|
||||||
writeObject(e.getValue());
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// Check that keys are strings, write entries in canonical order
|
|
||||||
List<String> keys = new ArrayList<>(m.size());
|
|
||||||
for (Object k : m.keySet()) {
|
|
||||||
if (!(k instanceof String)) throw new FormatException();
|
|
||||||
keys.add((String) k);
|
|
||||||
}
|
|
||||||
sort(keys);
|
|
||||||
for (String key : keys) {
|
|
||||||
writeString(key);
|
|
||||||
writeObject(m.get(key));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
out.write(END);
|
out.write(END);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeDictionaryStart() throws IOException {
|
||||||
|
out.write(DICTIONARY);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeDictionaryEnd() throws IOException {
|
||||||
|
out.write(END);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.bramble.keyagreement;
|
package org.briarproject.bramble.keyagreement;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
|
||||||
import org.briarproject.bramble.api.data.BdfWriter;
|
import org.briarproject.bramble.api.data.BdfWriter;
|
||||||
import org.briarproject.bramble.api.data.BdfWriterFactory;
|
import org.briarproject.bramble.api.data.BdfWriterFactory;
|
||||||
import org.briarproject.bramble.api.keyagreement.Payload;
|
import org.briarproject.bramble.api.keyagreement.Payload;
|
||||||
@@ -33,14 +32,13 @@ class PayloadEncoderImpl implements PayloadEncoder {
|
|||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||||
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
|
int formatIdAndVersion = (QR_FORMAT_ID << 5) | QR_FORMAT_VERSION;
|
||||||
out.write(formatIdAndVersion);
|
out.write(formatIdAndVersion);
|
||||||
BdfList payload = new BdfList();
|
|
||||||
payload.add(p.getCommitment());
|
|
||||||
for (TransportDescriptor d : p.getTransportDescriptors()) {
|
|
||||||
payload.add(d.getDescriptor());
|
|
||||||
}
|
|
||||||
BdfWriter w = bdfWriterFactory.createWriter(out);
|
BdfWriter w = bdfWriterFactory.createWriter(out);
|
||||||
try {
|
try {
|
||||||
w.writeList(payload);
|
w.writeListStart(); // Payload start
|
||||||
|
w.writeRaw(p.getCommitment());
|
||||||
|
for (TransportDescriptor d : p.getTransportDescriptors())
|
||||||
|
w.writeList(d.getDescriptor());
|
||||||
|
w.writeListEnd(); // Payload end
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
// Shouldn't happen with ByteArrayOutputStream
|
// Shouldn't happen with ByteArrayOutputStream
|
||||||
throw new AssertionError(e);
|
throw new AssertionError(e);
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ class PayloadParserImpl implements PayloadParser {
|
|||||||
List<TransportDescriptor> recognised = new ArrayList<>();
|
List<TransportDescriptor> recognised = new ArrayList<>();
|
||||||
for (int i = 1; i < payload.size(); i++) {
|
for (int i = 1; i < payload.size(); i++) {
|
||||||
BdfList descriptor = payload.getList(i);
|
BdfList descriptor = payload.getList(i);
|
||||||
int transportId = descriptor.getInt(0);
|
long transportId = descriptor.getLong(0);
|
||||||
if (transportId == TRANSPORT_ID_BLUETOOTH) {
|
if (transportId == TRANSPORT_ID_BLUETOOTH) {
|
||||||
TransportId id = BluetoothConstants.ID;
|
TransportId id = BluetoothConstants.ID;
|
||||||
recognised.add(new TransportDescriptor(id, descriptor));
|
recognised.add(new TransportDescriptor(id, descriptor));
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.bramble.mailbox;
|
package org.briarproject.bramble.mailbox;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.db.TransactionManager;
|
import org.briarproject.bramble.api.db.TransactionManager;
|
||||||
@@ -12,15 +11,12 @@ import org.briarproject.bramble.api.mailbox.MailboxSettingsManager;
|
|||||||
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
import org.briarproject.bramble.api.mailbox.MailboxStatus;
|
||||||
import org.briarproject.bramble.api.mailbox.MailboxVersion;
|
import org.briarproject.bramble.api.mailbox.MailboxVersion;
|
||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.util.Base32;
|
|
||||||
import org.briarproject.nullsafety.NotNullByDefault;
|
import org.briarproject.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Matcher;
|
|
||||||
import java.util.regex.Pattern;
|
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
@@ -30,7 +26,6 @@ import javax.inject.Inject;
|
|||||||
import static java.util.logging.Level.WARNING;
|
import static java.util.logging.Level.WARNING;
|
||||||
import static java.util.logging.Logger.getLogger;
|
import static java.util.logging.Logger.getLogger;
|
||||||
import static org.briarproject.bramble.util.LogUtils.logException;
|
import static org.briarproject.bramble.util.LogUtils.logException;
|
||||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
|
||||||
|
|
||||||
@Immutable
|
@Immutable
|
||||||
@NotNullByDefault
|
@NotNullByDefault
|
||||||
@@ -103,22 +98,6 @@ class MailboxManagerImpl implements MailboxManager {
|
|||||||
return created;
|
return created;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public String convertBase32Payload(String base32Payload)
|
|
||||||
throws FormatException {
|
|
||||||
Pattern regex = Pattern.compile("(briar-mailbox://)?([a-z2-7]{104})");
|
|
||||||
Matcher matcher = regex.matcher(base32Payload);
|
|
||||||
if (!matcher.find()) throw new FormatException();
|
|
||||||
String base32 = matcher.group(2);
|
|
||||||
byte[] payloadBytes;
|
|
||||||
try {
|
|
||||||
payloadBytes = Base32.decode(base32, false);
|
|
||||||
} catch (IllegalArgumentException e) {
|
|
||||||
throw new FormatException();
|
|
||||||
}
|
|
||||||
return new String(payloadBytes, ISO_8859_1);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean checkConnection() {
|
public boolean checkConnection() {
|
||||||
List<MailboxVersion> versions = null;
|
List<MailboxVersion> versions = null;
|
||||||
|
|||||||
@@ -419,7 +419,7 @@ class LanTcpPlugin extends TcpPlugin {
|
|||||||
private InetSocketAddress parseSocketAddress(BdfList descriptor)
|
private InetSocketAddress parseSocketAddress(BdfList descriptor)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
byte[] address = descriptor.getRaw(1);
|
byte[] address = descriptor.getRaw(1);
|
||||||
int port = descriptor.getInt(2);
|
int port = descriptor.getLong(2).intValue();
|
||||||
if (port < 1 || port > MAX_16_BIT_UNSIGNED) throw new FormatException();
|
if (port < 1 || port > MAX_16_BIT_UNSIGNED) throw new FormatException();
|
||||||
try {
|
try {
|
||||||
InetAddress addr = InetAddress.getByAddress(address);
|
InetAddress addr = InetAddress.getByAddress(address);
|
||||||
|
|||||||
@@ -55,6 +55,7 @@ import java.util.concurrent.Executor;
|
|||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
|
import java.util.zip.ZipInputStream;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.annotation.concurrent.GuardedBy;
|
import javax.annotation.concurrent.GuardedBy;
|
||||||
@@ -100,7 +101,6 @@ import static org.briarproject.bramble.util.LogUtils.logException;
|
|||||||
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
|
import static org.briarproject.bramble.util.PrivacyUtils.scrubOnion;
|
||||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
||||||
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
import static org.briarproject.bramble.util.StringUtils.isNullOrEmpty;
|
||||||
import static org.briarproject.nullsafety.NullSafety.requireNonNull;
|
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -348,7 +348,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Installing Tor binary for " + architecture);
|
LOG.info("Installing Tor binary for " + architecture);
|
||||||
File torFile = getTorExecutableFile();
|
File torFile = getTorExecutableFile();
|
||||||
extract(getExecutableInputStream("tor"), torFile);
|
extract(getTorInputStream(), torFile);
|
||||||
if (!torFile.setExecutable(true, true)) throw new IOException();
|
if (!torFile.setExecutable(true, true)) throw new IOException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,7 +356,7 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Installing obfs4proxy binary for " + architecture);
|
LOG.info("Installing obfs4proxy binary for " + architecture);
|
||||||
File obfs4File = getObfs4ExecutableFile();
|
File obfs4File = getObfs4ExecutableFile();
|
||||||
extract(getExecutableInputStream("obfs4proxy"), obfs4File);
|
extract(getObfs4InputStream(), obfs4File);
|
||||||
if (!obfs4File.setExecutable(true, true)) throw new IOException();
|
if (!obfs4File.setExecutable(true, true)) throw new IOException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -364,18 +364,28 @@ abstract class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
|
|||||||
if (LOG.isLoggable(INFO))
|
if (LOG.isLoggable(INFO))
|
||||||
LOG.info("Installing snowflake binary for " + architecture);
|
LOG.info("Installing snowflake binary for " + architecture);
|
||||||
File snowflakeFile = getSnowflakeExecutableFile();
|
File snowflakeFile = getSnowflakeExecutableFile();
|
||||||
extract(getExecutableInputStream("snowflake"), snowflakeFile);
|
extract(getSnowflakeInputStream(), snowflakeFile);
|
||||||
if (!snowflakeFile.setExecutable(true, true)) throw new IOException();
|
if (!snowflakeFile.setExecutable(true, true)) throw new IOException();
|
||||||
}
|
}
|
||||||
|
|
||||||
private InputStream getExecutableInputStream(String basename) {
|
private InputStream getTorInputStream() throws IOException {
|
||||||
String ext = getExecutableExtension();
|
return getZipInputStream("tor");
|
||||||
return requireNonNull(resourceProvider
|
|
||||||
.getResourceInputStream(architecture + "/" + basename, ext));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String getExecutableExtension() {
|
private InputStream getObfs4InputStream() throws IOException {
|
||||||
return "";
|
return getZipInputStream("obfs4proxy");
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream getSnowflakeInputStream() throws IOException {
|
||||||
|
return getZipInputStream("snowflake");
|
||||||
|
}
|
||||||
|
|
||||||
|
private InputStream getZipInputStream(String basename) throws IOException {
|
||||||
|
InputStream in = resourceProvider
|
||||||
|
.getResourceInputStream(basename + "_" + architecture, ".zip");
|
||||||
|
ZipInputStream zin = new ZipInputStream(in);
|
||||||
|
if (zin.getNextEntry() == null) throw new IOException();
|
||||||
|
return zin;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void append(StringBuilder strb, String name, Object value) {
|
private static void append(StringBuilder strb, String name, Object value) {
|
||||||
|
|||||||
@@ -201,7 +201,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
// Retrieve and parse the latest local properties
|
// Retrieve and parse the latest local properties
|
||||||
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
for (Entry<TransportId, LatestUpdate> e : latest.entrySet()) {
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
e.getValue().messageId, false);
|
e.getValue().messageId);
|
||||||
local.put(e.getKey(), parseProperties(message));
|
local.put(e.getKey(), parseProperties(message));
|
||||||
}
|
}
|
||||||
return local;
|
return local;
|
||||||
@@ -222,7 +222,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
if (latest != null) {
|
if (latest != null) {
|
||||||
// Retrieve and parse the latest local properties
|
// Retrieve and parse the latest local properties
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
latest.messageId, false);
|
latest.messageId);
|
||||||
p = parseProperties(message);
|
p = parseProperties(message);
|
||||||
}
|
}
|
||||||
return p == null ? new TransportProperties() : p;
|
return p == null ? new TransportProperties() : p;
|
||||||
@@ -252,7 +252,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
local = new TransportProperties();
|
local = new TransportProperties();
|
||||||
} else {
|
} else {
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
latest.messageId, false);
|
latest.messageId);
|
||||||
local = parseProperties(message);
|
local = parseProperties(message);
|
||||||
}
|
}
|
||||||
storeLocalProperties(txn, c, t, local);
|
storeLocalProperties(txn, c, t, local);
|
||||||
@@ -272,8 +272,8 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
remote = new TransportProperties();
|
remote = new TransportProperties();
|
||||||
} else {
|
} else {
|
||||||
// Retrieve and parse the latest remote properties
|
// Retrieve and parse the latest remote properties
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message =
|
||||||
latest.messageId, false);
|
clientHelper.getMessageAsList(txn, latest.messageId);
|
||||||
remote = parseProperties(message);
|
remote = parseProperties(message);
|
||||||
}
|
}
|
||||||
// Merge in any discovered properties
|
// Merge in any discovered properties
|
||||||
@@ -317,7 +317,7 @@ class TransportPropertyManagerImpl implements TransportPropertyManager,
|
|||||||
changed = true;
|
changed = true;
|
||||||
} else {
|
} else {
|
||||||
BdfList message = clientHelper.getMessageAsList(txn,
|
BdfList message = clientHelper.getMessageAsList(txn,
|
||||||
latest.messageId, false);
|
latest.messageId);
|
||||||
TransportProperties old = parseProperties(message);
|
TransportProperties old = parseProperties(message);
|
||||||
merged = new TransportProperties(old);
|
merged = new TransportProperties(old);
|
||||||
for (Entry<String, String> e : p.entrySet()) {
|
for (Entry<String, String> e : p.entrySet()) {
|
||||||
|
|||||||
@@ -27,10 +27,7 @@ class TransportPropertyValidator extends BdfMessageValidator {
|
|||||||
|
|
||||||
TransportPropertyValidator(ClientHelper clientHelper,
|
TransportPropertyValidator(ClientHelper clientHelper,
|
||||||
MetadataEncoder metadataEncoder, Clock clock) {
|
MetadataEncoder metadataEncoder, Clock clock) {
|
||||||
// Accept transport properties in non-canonical form
|
super(clientHelper, metadataEncoder, clock);
|
||||||
// TODO: Remove this after a reasonable migration period
|
|
||||||
// (added 2023-02-17)
|
|
||||||
super(clientHelper, metadataEncoder, clock, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
|||||||
import static org.briarproject.bramble.api.sync.RecordTypes.PRIORITY;
|
import static org.briarproject.bramble.api.sync.RecordTypes.PRIORITY;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.VERSIONS;
|
import static org.briarproject.bramble.api.sync.RecordTypes.VERSIONS;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_LENGTH;
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_SUPPORTED_VERSIONS;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_SUPPORTED_VERSIONS;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.PRIORITY_NONCE_BYTES;
|
import static org.briarproject.bramble.api.sync.SyncConstants.PRIORITY_NONCE_BYTES;
|
||||||
@@ -127,8 +126,6 @@ class SyncRecordReaderImpl implements SyncRecordReader {
|
|||||||
byte[] payload = nextRecord.getPayload();
|
byte[] payload = nextRecord.getPayload();
|
||||||
if (payload.length <= MESSAGE_HEADER_LENGTH)
|
if (payload.length <= MESSAGE_HEADER_LENGTH)
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
if (payload.length > MAX_MESSAGE_LENGTH)
|
|
||||||
throw new FormatException();
|
|
||||||
// Validate timestamp
|
// Validate timestamp
|
||||||
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
|
long timestamp = ByteUtils.readUint64(payload, UniqueId.LENGTH);
|
||||||
if (timestamp < 0) throw new FormatException();
|
if (timestamp < 0) throw new FormatException();
|
||||||
|
|||||||
@@ -32,7 +32,8 @@ class SessionParserImpl implements SessionParser {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Session parseSession(BdfDictionary meta) throws FormatException {
|
public Session parseSession(BdfDictionary meta) throws FormatException {
|
||||||
State state = State.fromValue(meta.getInt(SESSION_KEY_STATE));
|
State state =
|
||||||
|
State.fromValue(meta.getLong(SESSION_KEY_STATE).intValue());
|
||||||
|
|
||||||
MessageId lastLocalMessageId = null;
|
MessageId lastLocalMessageId = null;
|
||||||
byte[] lastLocalMessageIdBytes =
|
byte[] lastLocalMessageIdBytes =
|
||||||
@@ -55,9 +56,9 @@ class SessionParserImpl implements SessionParser {
|
|||||||
Long localTimestamp = meta.getOptionalLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
Long localTimestamp = meta.getOptionalLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
||||||
|
|
||||||
KeySetId keySetId = null;
|
KeySetId keySetId = null;
|
||||||
Integer keySetIdInt = meta.getOptionalInt(SESSION_KEY_KEY_SET_ID);
|
Long keySetIdLong = meta.getOptionalLong(SESSION_KEY_KEY_SET_ID);
|
||||||
if (keySetIdInt != null) {
|
if (keySetIdLong != null) {
|
||||||
keySetId = new KeySetId(keySetIdInt);
|
keySetId = new KeySetId(keySetIdLong.intValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Session(state, lastLocalMessageId, localKeyPair,
|
return new Session(state, lastLocalMessageId, localKeyPair,
|
||||||
|
|||||||
@@ -177,8 +177,8 @@ class TransportKeyAgreementManagerImpl extends BdfIncomingMessageHook
|
|||||||
protected DeliveryAction incomingMessage(Transaction txn, Message m,
|
protected DeliveryAction incomingMessage(Transaction txn, Message m,
|
||||||
BdfList body, BdfDictionary meta)
|
BdfList body, BdfDictionary meta)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
MessageType type =
|
MessageType type = MessageType.fromValue(
|
||||||
MessageType.fromValue(meta.getInt(MSG_KEY_MESSAGE_TYPE));
|
meta.getLong(MSG_KEY_MESSAGE_TYPE).intValue());
|
||||||
TransportId t = new TransportId(meta.getString(MSG_KEY_TRANSPORT_ID));
|
TransportId t = new TransportId(meta.getString(MSG_KEY_TRANSPORT_ID));
|
||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("Received " + type + " message for " + t);
|
LOG.info("Received " + type + " message for " + t);
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ class TransportKeyAgreementValidator extends BdfMessageValidator {
|
|||||||
@Override
|
@Override
|
||||||
protected BdfMessageContext validateMessage(Message m, Group g,
|
protected BdfMessageContext validateMessage(Message m, Group g,
|
||||||
BdfList body) throws FormatException {
|
BdfList body) throws FormatException {
|
||||||
MessageType type = MessageType.fromValue(body.getInt(0));
|
MessageType type = MessageType.fromValue(body.getLong(0).intValue());
|
||||||
if (type == KEY) return validateKeyMessage(m.getTimestamp(), body);
|
if (type == KEY) return validateKeyMessage(m.getTimestamp(), body);
|
||||||
else if (type == ACTIVATE) return validateActivateMessage(body);
|
else if (type == ACTIVATE) return validateActivateMessage(body);
|
||||||
else throw new AssertionError();
|
else throw new AssertionError();
|
||||||
|
|||||||
@@ -301,8 +301,8 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
|||||||
for (int i = 0; i < size; i++) {
|
for (int i = 0; i < size; i++) {
|
||||||
BdfList cv = body.getList(i);
|
BdfList cv = body.getList(i);
|
||||||
ClientId clientId = new ClientId(cv.getString(0));
|
ClientId clientId = new ClientId(cv.getString(0));
|
||||||
int majorVersion = cv.getInt(1);
|
int majorVersion = cv.getLong(1).intValue();
|
||||||
int minorVersion = cv.getInt(2);
|
int minorVersion = cv.getLong(2).intValue();
|
||||||
parsed.add(new ClientVersion(clientId, majorVersion, minorVersion));
|
parsed.add(new ClientVersion(clientId, majorVersion, minorVersion));
|
||||||
}
|
}
|
||||||
return parsed;
|
return parsed;
|
||||||
@@ -408,8 +408,8 @@ class ClientVersioningManagerImpl implements ClientVersioningManager,
|
|||||||
throws FormatException {
|
throws FormatException {
|
||||||
// Client ID, major version, minor version, active
|
// Client ID, major version, minor version, active
|
||||||
ClientId clientId = new ClientId(clientState.getString(0));
|
ClientId clientId = new ClientId(clientState.getString(0));
|
||||||
int majorVersion = clientState.getInt(1);
|
int majorVersion = clientState.getLong(1).intValue();
|
||||||
int minorVersion = clientState.getInt(2);
|
int minorVersion = clientState.getLong(2).intValue();
|
||||||
boolean active = clientState.getBoolean(3);
|
boolean active = clientState.getBoolean(3);
|
||||||
return new ClientState(clientId, majorVersion, minorVersion, active);
|
return new ClientState(clientId, majorVersion, minorVersion, active);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,9 +43,9 @@ class ClientVersioningValidator extends BdfMessageValidator {
|
|||||||
checkSize(clientState, 4);
|
checkSize(clientState, 4);
|
||||||
String clientId = clientState.getString(0);
|
String clientId = clientState.getString(0);
|
||||||
checkLength(clientId, 1, MAX_CLIENT_ID_LENGTH);
|
checkLength(clientId, 1, MAX_CLIENT_ID_LENGTH);
|
||||||
int majorVersion = clientState.getInt(1);
|
int majorVersion = clientState.getLong(1).intValue();
|
||||||
if (majorVersion < 0) throw new FormatException();
|
if (majorVersion < 0) throw new FormatException();
|
||||||
int minorVersion = clientState.getInt(2);
|
int minorVersion = clientState.getLong(2).intValue();
|
||||||
if (minorVersion < 0) throw new FormatException();
|
if (minorVersion < 0) throw new FormatException();
|
||||||
clientState.getBoolean(3);
|
clientState.getBoolean(3);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,21 +10,22 @@ d Bridge obfs4 146.57.248.225:22 10A6CD36A537FCE513A322361547444B393989F0 cert=K
|
|||||||
d Bridge obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0
|
d Bridge obfs4 45.145.95.6:27015 C5B7CD6946FF10C5B3E89691A7D3F2C122D2117C cert=TD7PbUO0/0k6xYHMPW3vJxICfkMZNdkRrb63Zhl5j9dW3iRGiCx0A7mPhe5T2EDzQ35+Zw iat-mode=0
|
||||||
d Bridge obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0
|
d Bridge obfs4 51.222.13.177:80 5EDAC3B810E12B01F6FD8050D2FD3E277B289A08 cert=2uplIpLQ0q9+0qMFrK5pkaYRDOe460LL9WHBvatgkuRr/SL31wBOEupaMMJ6koRE6Ld0ew iat-mode=0
|
||||||
n Bridge obfs4 185.181.11.86:443 A961609729E7FDF520B4E81F1F1B8FA1045285C3 cert=e5faG9Zk4Ni+e7z2YgGfevyKPQlMvkVGi4ublSsHYjaBovKeNXpOhbeFxzbZZoAzxAoGUQ iat-mode=0
|
n Bridge obfs4 185.181.11.86:443 A961609729E7FDF520B4E81F1F1B8FA1045285C3 cert=e5faG9Zk4Ni+e7z2YgGfevyKPQlMvkVGi4ublSsHYjaBovKeNXpOhbeFxzbZZoAzxAoGUQ iat-mode=0
|
||||||
|
n Bridge obfs4 93.95.226.151:41185 460B0CFFC0CF1D965F3DE064E08BA1915E7C916A cert=inluPzp5Jp5OzZar1eQb4dcQ/YlAj/v0kHAUCoCr3rmLt03+pVuVTjoH4mRy4+acXpn+Gw iat-mode=0
|
||||||
n Bridge obfs4 120.29.217.52:5223 40FE3DB9800272F9CDC76422F8ED7883280EE96D cert=/71PS4l8c/XJ4DIItlH9xMqNvPFg2RUTrHvPlQWh48u5et8h/yyyjCcYphUadDsfBWpaGQ iat-mode=0
|
n Bridge obfs4 120.29.217.52:5223 40FE3DB9800272F9CDC76422F8ED7883280EE96D cert=/71PS4l8c/XJ4DIItlH9xMqNvPFg2RUTrHvPlQWh48u5et8h/yyyjCcYphUadDsfBWpaGQ iat-mode=0
|
||||||
n Bridge obfs4 185.177.207.138:8443 53716FE26F23C8C6A71A2BC5D9D8DC64747278C7 cert=6jcYVilMEzxdsWghSrQFpYYJlkkir/GPIXw/EnddUK3S8ToVpMG8u1SwMOEdEs735RrMHw iat-mode=0
|
n Bridge obfs4 185.177.207.138:8443 53716FE26F23C8C6A71A2BC5D9D8DC64747278C7 cert=6jcYVilMEzxdsWghSrQFpYYJlkkir/GPIXw/EnddUK3S8ToVpMG8u1SwMOEdEs735RrMHw iat-mode=0
|
||||||
|
n Bridge obfs4 104.168.68.90:443 ED55B3C321E44EA7E50EF568C8A63CF75E89A58C cert=fgonxDvltTp8nmcOE9sUG94eOAALxETVVXAwnTZJLPpf7rjPuTp+abKl4VyFkxfcLRr5KQ iat-mode=0
|
||||||
n Bridge obfs4 45.142.181.131:42069 6EBCF6B02DA2B982F4080A7119D737366AFB74FA cert=9HyWH/BCwWzNirZdTQtluCgJk+gFhpOqydIuyQ1iDvpnqsAynKF+zcPE/INZFefm86UlBg iat-mode=0
|
n Bridge obfs4 45.142.181.131:42069 6EBCF6B02DA2B982F4080A7119D737366AFB74FA cert=9HyWH/BCwWzNirZdTQtluCgJk+gFhpOqydIuyQ1iDvpnqsAynKF+zcPE/INZFefm86UlBg iat-mode=0
|
||||||
|
n Bridge obfs4 85.214.28.204:47111 78A36E46BB082A471848239D3F4390A8F8C6084D cert=96sr3eaUFBDu4wFVAQIfNFElh0UNuutJ/3/Fh2Vu2PHfacQ8bwfY02bwG351U8BZpLnfUQ iat-mode=0
|
||||||
n Bridge obfs4 152.67.77.101:4096 B82DB9CDDF887AB8A859420E07DF298E30AF8A6E cert=21OWn3yFo+hulmQNAOtF5uwwOqWtdT5PrLhk8BG9DpOd0/k5DEkQEYPyDdXbS9nZ0E5BJA iat-mode=0
|
n Bridge obfs4 152.67.77.101:4096 B82DB9CDDF887AB8A859420E07DF298E30AF8A6E cert=21OWn3yFo+hulmQNAOtF5uwwOqWtdT5PrLhk8BG9DpOd0/k5DEkQEYPyDdXbS9nZ0E5BJA iat-mode=0
|
||||||
|
n Bridge obfs4 185.103.252.72:443 75F15E9339FF572F88F5588D429FEA379744BC53 cert=nOZ/SaRE3L1dChvjfe0Ks/wM/F8iFhwd3g2G5zgtcLB8x+wiZRWCwjRrbbiQyb3Gh2mxRQ iat-mode=0
|
||||||
|
n Bridge obfs4 76.255.201.112:8888 96CF36C2ECCFB7376AB6BE905BECD2C2AE8AEFCD cert=+q0pjaiM0JMqHL/BKqCRD+pjflaw/S406eUDF7CnFgamvQW3l2HVLJhQ6uX9P8zff0PLGg iat-mode=0
|
||||||
n Bridge obfs4 94.142.246.132:8088 135C158527AA9FE9A2F26EC515EB6999D813D347 cert=wTUz0/5FhAZRkitil5MprGbSF3JzjxjxI1kAmxAdSeDy98NgcLr11f/qUXWDC76Y97RiSg iat-mode=0
|
n Bridge obfs4 94.142.246.132:8088 135C158527AA9FE9A2F26EC515EB6999D813D347 cert=wTUz0/5FhAZRkitil5MprGbSF3JzjxjxI1kAmxAdSeDy98NgcLr11f/qUXWDC76Y97RiSg iat-mode=0
|
||||||
|
n Bridge obfs4 20.102.79.78:22022 B5705F7E616DAB0F477E3E1ADC23E40413F683FE cert=1Cc/hwPtPjzFKGHVOP0j/qmBgnvquRx8+im35/u5TIYjDQ3FlMfA5VvTrQ/hbX8BZZooLQ iat-mode=0
|
||||||
n Bridge obfs4 152.70.180.20:1993 3327C43587E66AD5F874C4234A1D72C938AD7318 cert=s7xLRUO2psaX7TMUP2YhXdxItR4U6K7D+E3gQaS/+yWUppevtazIibq4dN1g5Reu6dD2QQ iat-mode=0
|
n Bridge obfs4 152.70.180.20:1993 3327C43587E66AD5F874C4234A1D72C938AD7318 cert=s7xLRUO2psaX7TMUP2YhXdxItR4U6K7D+E3gQaS/+yWUppevtazIibq4dN1g5Reu6dD2QQ iat-mode=0
|
||||||
n Bridge obfs4 144.202.12.254:10002 4E220F45CD404C8A3082A36326A5ED19BB8D4404 cert=iLz5YYWO4pUw7U7MRNOSvE0qO+IVeE4kVfFVWPO3coH3FmZtrkvlaTklfXxHZaCcXWBgaA iat-mode=0
|
n Bridge obfs4 144.202.12.254:10002 4E220F45CD404C8A3082A36326A5ED19BB8D4404 cert=iLz5YYWO4pUw7U7MRNOSvE0qO+IVeE4kVfFVWPO3coH3FmZtrkvlaTklfXxHZaCcXWBgaA iat-mode=0
|
||||||
n Bridge obfs4 109.14.168.159:5082 BFE1416DEFFE969581F016A4A319A87FFB26BA91 cert=n3X1CDdKBPXPIzfKh83p3ydfMzb0AD9gKC+/gIpHb7+xjjAnYO9x3LT+T/MvOIfAXxYySg iat-mode=0
|
n Bridge obfs4 109.14.168.159:5082 BFE1416DEFFE969581F016A4A319A87FFB26BA91 cert=n3X1CDdKBPXPIzfKh83p3ydfMzb0AD9gKC+/gIpHb7+xjjAnYO9x3LT+T/MvOIfAXxYySg iat-mode=0
|
||||||
|
n Bridge obfs4 45.150.172.16:80 82849E69CBB25EA7F479155F7DCD89D85717FF47 cert=+Krdu1jmVQOxWkMj0mqJHgwbQV49eyD6mZDS+mRExssWNHosa60g4P5Gp81sBJKzN8NrSw iat-mode=0
|
||||||
n Bridge obfs4 185.177.207.132:8443 4FB781F7A9DD39DA53A7996907817FC479874D19 cert=UL2gCAXWW5kEWY4TQ0lNeu6OAmzh40bXYVhMnTWVG8USnyy/zEKGSIPgmwTDMumWr9c1Pg iat-mode=0
|
n Bridge obfs4 185.177.207.132:8443 4FB781F7A9DD39DA53A7996907817FC479874D19 cert=UL2gCAXWW5kEWY4TQ0lNeu6OAmzh40bXYVhMnTWVG8USnyy/zEKGSIPgmwTDMumWr9c1Pg iat-mode=0
|
||||||
n Bridge obfs4 213.108.110.149:7499 519344140473CF91030B08F91521F9A6C144ED6C cert=k9fSL/d491qAkGmi2VeSwVlfuyO02jBeN54qxzzQISxpfm3b+a6kJpo8/Bfy1ACbHZIJUg iat-mode=0
|
|
||||||
n Bridge obfs4 158.174.114.97:3456 32665CD4CBE19092CA47A53D317B8BFF5810441C cert=ne5Zt0TcMedSGmFwAs/AV6J6E9Hn7mG5mR6vQNpEfyuCZK1VRpQvU1LvvtesSu4CXqZtYQ iat-mode=0
|
|
||||||
n Bridge obfs4 64.4.175.62:8000 8B72740D150795ACB5101AA5F95D1ACDA4FE6B3E cert=vduuNhJ5U/8hjZmllP6AFfXSlSZsnrimdR8Tm8DY9dxWS4n2j92fNc0qHihUwRqwcOfIcg iat-mode=0
|
|
||||||
n Bridge obfs4 82.64.115.17:990 B08238781C2CD80DBD95AEABEB6F6C75F2E2CEB6 cert=1udeMlFNs3sJ20zwpPE6nShZqqwDb3F1ET4KzfSfD+fktkue9zNx9H3t+yLCPAsg+6UTUA iat-mode=1
|
|
||||||
n Bridge obfs4 87.161.120.147:9292 9418EEBE8AEAE32CC381AF51610366E8B24651E0 cert=DFRm74qsD1i2/ypaGochpX6CS1j9JTFAKEYaHXrgrx6M2LG5Cvppdt3Ob7lULfhqgtAUdg iat-mode=0
|
|
||||||
n Bridge obfs4 157.90.245.231:8599 C23CD468EC04555E2B37BE81A771E681049DEA6A cert=UsmDelrbwg4jc6BMvZJ0TS8klUIa2qkbRu3xwQc3ZXPEgpMqyTYUxcVwyPbIU5KmAHsmAA iat-mode=0
|
|
||||||
v Bridge 92.243.15.235:9001 477EAD3C04036B48235F1F27FC91420A286A4B7F
|
v Bridge 92.243.15.235:9001 477EAD3C04036B48235F1F27FC91420A286A4B7F
|
||||||
v Bridge 213.108.108.145:17674 A39C0FE47963B6E8CFE9815549864DE544935A31
|
v Bridge 213.108.108.145:17674 A39C0FE47963B6E8CFE9815549864DE544935A31
|
||||||
v Bridge 213.196.191.96:9060 05E222E2A8C234234FE0CEB58B08A93B8FC360DB
|
v Bridge 213.196.191.96:9060 05E222E2A8C234234FE0CEB58B08A93B8FC360DB
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(timestamp - MAX_CLOCK_DIFFERENCE));
|
will(returnValue(timestamp - MAX_CLOCK_DIFFERENCE));
|
||||||
oneOf(clientHelper).toList(message, true);
|
oneOf(clientHelper).toList(message.getBody());
|
||||||
will(returnValue(body));
|
will(returnValue(body));
|
||||||
oneOf(metadataEncoder).encode(dictionary);
|
oneOf(metadataEncoder).encode(dictionary);
|
||||||
will(returnValue(meta));
|
will(returnValue(meta));
|
||||||
@@ -86,7 +86,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(timestamp));
|
will(returnValue(timestamp));
|
||||||
oneOf(clientHelper).toList(shortMessage, true);
|
oneOf(clientHelper).toList(shortMessage.getBody());
|
||||||
will(returnValue(body));
|
will(returnValue(body));
|
||||||
oneOf(metadataEncoder).encode(dictionary);
|
oneOf(metadataEncoder).encode(dictionary);
|
||||||
will(returnValue(meta));
|
will(returnValue(meta));
|
||||||
@@ -114,7 +114,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(timestamp));
|
will(returnValue(timestamp));
|
||||||
oneOf(clientHelper).toList(message, true);
|
oneOf(clientHelper).toList(message.getBody());
|
||||||
will(throwException(new FormatException()));
|
will(throwException(new FormatException()));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ public class BdfMessageValidatorTest extends ValidatorTestCase {
|
|||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(clock).currentTimeMillis();
|
oneOf(clock).currentTimeMillis();
|
||||||
will(returnValue(timestamp));
|
will(returnValue(timestamp));
|
||||||
oneOf(clientHelper).toList(message, true);
|
oneOf(clientHelper).toList(message.getBody());
|
||||||
will(returnValue(body));
|
will(returnValue(body));
|
||||||
}});
|
}});
|
||||||
|
|
||||||
|
|||||||
@@ -546,7 +546,7 @@ public class ClientHelperImplTest extends BrambleMockTestCase {
|
|||||||
|
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
oneOf(bdfReaderFactory)
|
oneOf(bdfReaderFactory)
|
||||||
.createReader(with(any(InputStream.class)), with(true));
|
.createReader(with(any(InputStream.class)));
|
||||||
will(returnValue(bdfReader));
|
will(returnValue(bdfReader));
|
||||||
oneOf(bdfReader).readList();
|
oneOf(bdfReader).readList();
|
||||||
will(returnValue(list));
|
will(returnValue(list));
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.bramble.data;
|
package org.briarproject.bramble.data;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -32,14 +31,11 @@ public class BdfReaderImplFuzzingTest extends BrambleTestCase {
|
|||||||
buf[1] = 0x14; // Length 20 bytes
|
buf[1] = 0x14; // Length 20 bytes
|
||||||
in.reset();
|
in.reset();
|
||||||
BdfReaderImpl r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
BdfReaderImpl r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
||||||
DEFAULT_MAX_BUFFER_SIZE, true);
|
DEFAULT_MAX_BUFFER_SIZE);
|
||||||
try {
|
int length = r.readString().length();
|
||||||
int length = r.readString().length();
|
assertTrue(length >= 0);
|
||||||
assertTrue(length <= 20);
|
assertTrue(length <= 20);
|
||||||
assertTrue(r.eof());
|
assertTrue(r.eof());
|
||||||
} catch (FormatException e) {
|
|
||||||
// Expected when bytes are not valid UTF-8
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ import java.io.ByteArrayInputStream;
|
|||||||
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
import static org.briarproject.bramble.api.data.BdfDictionary.NULL_VALUE;
|
||||||
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE;
|
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE;
|
||||||
import static org.briarproject.bramble.data.BdfReaderImpl.DEFAULT_NESTED_LIMIT;
|
import static org.briarproject.bramble.data.BdfReaderImpl.DEFAULT_NESTED_LIMIT;
|
||||||
import static org.briarproject.bramble.util.StringUtils.UTF_8;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
||||||
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
import static org.briarproject.bramble.util.StringUtils.getRandomString;
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
||||||
@@ -89,18 +88,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
assertTrue(r.eof());
|
assertTrue(r.eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadLong16CouldHaveBeenLong8Max() throws Exception {
|
|
||||||
setContents("22" + "007F");
|
|
||||||
r.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadLong16CouldHaveBeenLong8Min() throws Exception {
|
|
||||||
setContents("22" + "FF80");
|
|
||||||
r.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipLong16() throws Exception {
|
public void testSkipLong16() throws Exception {
|
||||||
setContents("22" + "0080");
|
setContents("22" + "0080");
|
||||||
@@ -119,18 +106,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
assertTrue(r.eof());
|
assertTrue(r.eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadLong32CouldHaveBeenLong16Max() throws Exception {
|
|
||||||
setContents("24" + "00007FFF");
|
|
||||||
r.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadLong32CouldHaveBeenLong16Min() throws Exception {
|
|
||||||
setContents("24" + "FFFF8000");
|
|
||||||
r.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipLong32() throws Exception {
|
public void testSkipLong32() throws Exception {
|
||||||
setContents("24" + "00008000");
|
setContents("24" + "00008000");
|
||||||
@@ -149,48 +124,13 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
assertTrue(r.eof());
|
assertTrue(r.eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadLong64CouldHaveBeenLong32Max() throws Exception {
|
|
||||||
setContents("28" + "000000007FFFFFFF");
|
|
||||||
r.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadLong64CouldHaveBeenLong32Min() throws Exception {
|
|
||||||
setContents("28" + "FFFFFFFF80000000");
|
|
||||||
r.readLong();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipLong64() throws Exception {
|
public void testSkipLong() throws Exception {
|
||||||
setContents("28" + "0000000080000000");
|
setContents("28" + "0000000080000000");
|
||||||
r.skipLong();
|
r.skipLong();
|
||||||
assertTrue(r.eof());
|
assertTrue(r.eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testReadInt() throws Exception {
|
|
||||||
setContents("21" + "7F" + "21" + "80"
|
|
||||||
+ "22" + "7FFF" + "22" + "8000"
|
|
||||||
+ "24" + "7FFFFFFF" + "24" + "80000000");
|
|
||||||
assertEquals(Byte.MAX_VALUE, r.readInt());
|
|
||||||
assertEquals(Byte.MIN_VALUE, r.readInt());
|
|
||||||
assertEquals(Short.MAX_VALUE, r.readInt());
|
|
||||||
assertEquals(Short.MIN_VALUE, r.readInt());
|
|
||||||
assertEquals(Integer.MAX_VALUE, r.readInt());
|
|
||||||
assertEquals(Integer.MIN_VALUE, r.readInt());
|
|
||||||
assertTrue(r.eof());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testSkipInt() throws Exception {
|
|
||||||
setContents("21" + "7F" + "22" + "7FFF" + "24" + "7FFFFFFF");
|
|
||||||
r.skipInt();
|
|
||||||
r.skipInt();
|
|
||||||
r.skipInt();
|
|
||||||
assertTrue(r.eof());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadDouble() throws Exception {
|
public void testReadDouble() throws Exception {
|
||||||
// http://babbage.cs.qc.edu/IEEE-754/Decimal.html
|
// http://babbage.cs.qc.edu/IEEE-754/Decimal.html
|
||||||
@@ -222,7 +162,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testReadString8() throws Exception {
|
public void testReadString8() throws Exception {
|
||||||
String longest = getRandomString(Byte.MAX_VALUE);
|
String longest = getRandomString(Byte.MAX_VALUE);
|
||||||
String longHex = toHexString(longest.getBytes(UTF_8));
|
String longHex = toHexString(longest.getBytes("UTF-8"));
|
||||||
// "foo", the empty string, and 127 random letters
|
// "foo", the empty string, and 127 random letters
|
||||||
setContents("41" + "03" + "666F6F" + "41" + "00" +
|
setContents("41" + "03" + "666F6F" + "41" + "00" +
|
||||||
"41" + "7F" + longHex);
|
"41" + "7F" + longHex);
|
||||||
@@ -246,7 +186,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testSkipString8() throws Exception {
|
public void testSkipString8() throws Exception {
|
||||||
String longest = getRandomString(Byte.MAX_VALUE);
|
String longest = getRandomString(Byte.MAX_VALUE);
|
||||||
String longHex = toHexString(longest.getBytes(UTF_8));
|
String longHex = toHexString(longest.getBytes("UTF-8"));
|
||||||
// "foo", the empty string, and 127 random letters
|
// "foo", the empty string, and 127 random letters
|
||||||
setContents("41" + "03" + "666F6F" + "41" + "00" +
|
setContents("41" + "03" + "666F6F" + "41" + "00" +
|
||||||
"41" + "7F" + longHex);
|
"41" + "7F" + longHex);
|
||||||
@@ -259,9 +199,9 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testReadString16() throws Exception {
|
public void testReadString16() throws Exception {
|
||||||
String shortest = getRandomString(Byte.MAX_VALUE + 1);
|
String shortest = getRandomString(Byte.MAX_VALUE + 1);
|
||||||
String shortHex = toHexString(shortest.getBytes(UTF_8));
|
String shortHex = toHexString(shortest.getBytes("UTF-8"));
|
||||||
String longest = getRandomString(Short.MAX_VALUE);
|
String longest = getRandomString(Short.MAX_VALUE);
|
||||||
String longHex = toHexString(longest.getBytes(UTF_8));
|
String longHex = toHexString(longest.getBytes("UTF-8"));
|
||||||
// 128 random letters and 2^15 -1 random letters
|
// 128 random letters and 2^15 -1 random letters
|
||||||
setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
|
setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
|
||||||
assertEquals(shortest, r.readString());
|
assertEquals(shortest, r.readString());
|
||||||
@@ -273,7 +213,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
public void testReadString16ChecksMaxLength() throws Exception {
|
public void testReadString16ChecksMaxLength() throws Exception {
|
||||||
int maxBufferSize = Byte.MAX_VALUE + 1;
|
int maxBufferSize = Byte.MAX_VALUE + 1;
|
||||||
String valid = getRandomString(Byte.MAX_VALUE + 1);
|
String valid = getRandomString(Byte.MAX_VALUE + 1);
|
||||||
String validHex = toHexString(valid.getBytes(UTF_8));
|
String validHex = toHexString(valid.getBytes("UTF-8"));
|
||||||
String invalidhex = validHex + "20";
|
String invalidhex = validHex + "20";
|
||||||
// 128 random letters, the same plus a space
|
// 128 random letters, the same plus a space
|
||||||
setContents("42" + "0080" + validHex
|
setContents("42" + "0080" + validHex
|
||||||
@@ -283,20 +223,12 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
r.readString();
|
r.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadString16CouldHaveBeenString8() throws Exception {
|
|
||||||
String longest = getRandomString(Byte.MAX_VALUE);
|
|
||||||
String longHex = toHexString(longest.getBytes(UTF_8));
|
|
||||||
setContents("42" + "007F" + longHex);
|
|
||||||
r.readString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipString16() throws Exception {
|
public void testSkipString16() throws Exception {
|
||||||
String shortest = getRandomString(Byte.MAX_VALUE + 1);
|
String shortest = getRandomString(Byte.MAX_VALUE + 1);
|
||||||
String shortHex = toHexString(shortest.getBytes(UTF_8));
|
String shortHex = toHexString(shortest.getBytes("UTF-8"));
|
||||||
String longest = getRandomString(Short.MAX_VALUE);
|
String longest = getRandomString(Short.MAX_VALUE);
|
||||||
String longHex = toHexString(longest.getBytes(UTF_8));
|
String longHex = toHexString(longest.getBytes("UTF-8"));
|
||||||
// 128 random letters and 2^15 - 1 random letters
|
// 128 random letters and 2^15 - 1 random letters
|
||||||
setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
|
setContents("42" + "0080" + shortHex + "42" + "7FFF" + longHex);
|
||||||
r.skipString();
|
r.skipString();
|
||||||
@@ -307,7 +239,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testReadString32() throws Exception {
|
public void testReadString32() throws Exception {
|
||||||
String shortest = getRandomString(Short.MAX_VALUE + 1);
|
String shortest = getRandomString(Short.MAX_VALUE + 1);
|
||||||
String shortHex = toHexString(shortest.getBytes(UTF_8));
|
String shortHex = toHexString(shortest.getBytes("UTF-8"));
|
||||||
// 2^15 random letters
|
// 2^15 random letters
|
||||||
setContents("44" + "00008000" + shortHex);
|
setContents("44" + "00008000" + shortHex);
|
||||||
assertEquals(shortest, r.readString());
|
assertEquals(shortest, r.readString());
|
||||||
@@ -318,7 +250,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
public void testReadString32ChecksMaxLength() throws Exception {
|
public void testReadString32ChecksMaxLength() throws Exception {
|
||||||
int maxBufferSize = Short.MAX_VALUE + 1;
|
int maxBufferSize = Short.MAX_VALUE + 1;
|
||||||
String valid = getRandomString(maxBufferSize);
|
String valid = getRandomString(maxBufferSize);
|
||||||
String validHex = toHexString(valid.getBytes(UTF_8));
|
String validHex = toHexString(valid.getBytes("UTF-8"));
|
||||||
String invalidHex = validHex + "20";
|
String invalidHex = validHex + "20";
|
||||||
// 2^15 random letters, the same plus a space
|
// 2^15 random letters, the same plus a space
|
||||||
setContents("44" + "00008000" + validHex +
|
setContents("44" + "00008000" + validHex +
|
||||||
@@ -328,18 +260,10 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
r.readString();
|
r.readString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadString32CouldHaveBeenString16() throws Exception {
|
|
||||||
String longest = getRandomString(Short.MAX_VALUE);
|
|
||||||
String longHex = toHexString(longest.getBytes(UTF_8));
|
|
||||||
setContents("44" + "00007FFF" + longHex);
|
|
||||||
r.readString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipString32() throws Exception {
|
public void testSkipString32() throws Exception {
|
||||||
String shortest = getRandomString(Short.MAX_VALUE + 1);
|
String shortest = getRandomString(Short.MAX_VALUE + 1);
|
||||||
String shortHex = toHexString(shortest.getBytes(UTF_8));
|
String shortHex = toHexString(shortest.getBytes("UTF-8"));
|
||||||
// 2^15 random letters, twice
|
// 2^15 random letters, twice
|
||||||
setContents("44" + "00008000" + shortHex +
|
setContents("44" + "00008000" + shortHex +
|
||||||
"44" + "00008000" + shortHex);
|
"44" + "00008000" + shortHex);
|
||||||
@@ -351,7 +275,7 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testReadUtf8String() throws Exception {
|
public void testReadUtf8String() throws Exception {
|
||||||
String unicode = "\uFDD0\uFDD1\uFDD2\uFDD3";
|
String unicode = "\uFDD0\uFDD1\uFDD2\uFDD3";
|
||||||
String hex = toHexString(unicode.getBytes(UTF_8));
|
String hex = toHexString(unicode.getBytes("UTF-8"));
|
||||||
// STRING_8 tag, "foo", the empty string, and the test string
|
// STRING_8 tag, "foo", the empty string, and the test string
|
||||||
setContents("41" + "03" + "666F6F" + "41" + "00" + "41" + "0C" + hex);
|
setContents("41" + "03" + "666F6F" + "41" + "00" + "41" + "0C" + hex);
|
||||||
assertEquals("foo", r.readString());
|
assertEquals("foo", r.readString());
|
||||||
@@ -424,14 +348,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
r.readRaw();
|
r.readRaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadRaw16CouldHaveBeenRaw8() throws Exception {
|
|
||||||
byte[] longest = new byte[Byte.MAX_VALUE];
|
|
||||||
String longHex = toHexString(longest);
|
|
||||||
setContents("52" + "007F" + longHex);
|
|
||||||
r.readRaw();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipRaw16() throws Exception {
|
public void testSkipRaw16() throws Exception {
|
||||||
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
|
byte[] shortest = new byte[Byte.MAX_VALUE + 1];
|
||||||
@@ -469,14 +385,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
r.readRaw();
|
r.readRaw();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testReadRaw32CouldHaveBeenRaw16() throws Exception {
|
|
||||||
byte[] longest = new byte[Short.MAX_VALUE];
|
|
||||||
String longHex = toHexString(longest);
|
|
||||||
setContents("54" + "00007FFF" + longHex);
|
|
||||||
r.readRaw();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipRaw32() throws Exception {
|
public void testSkipRaw32() throws Exception {
|
||||||
byte[] shortest = new byte[Short.MAX_VALUE + 1];
|
byte[] shortest = new byte[Short.MAX_VALUE + 1];
|
||||||
@@ -526,6 +434,25 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
r.readList();
|
r.readList();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadListManually() throws Exception {
|
||||||
|
// A list containing 1, "foo", and null
|
||||||
|
setContents("60" + "21" + "01" +
|
||||||
|
"41" + "03" + "666F6F" +
|
||||||
|
"00" + "80");
|
||||||
|
r.readListStart();
|
||||||
|
assertFalse(r.hasListEnd());
|
||||||
|
assertEquals(1, r.readLong());
|
||||||
|
assertFalse(r.hasListEnd());
|
||||||
|
assertEquals("foo", r.readString());
|
||||||
|
assertFalse(r.hasListEnd());
|
||||||
|
assertTrue(r.hasNull());
|
||||||
|
r.readNull();
|
||||||
|
assertTrue(r.hasListEnd());
|
||||||
|
r.readListEnd();
|
||||||
|
assertTrue(r.eof());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipList() throws Exception {
|
public void testSkipList() throws Exception {
|
||||||
// A list containing 1, "foo", and 128
|
// A list containing 1, "foo", and 128
|
||||||
@@ -538,9 +465,9 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReadDictionary() throws Exception {
|
public void testReadDictionary() throws Exception {
|
||||||
// A dictionary containing "bar" -> null and "foo" -> 123
|
// A dictionary containing "foo" -> 123 and "bar" -> null
|
||||||
setContents("70" + "41" + "03" + "626172" + "00" +
|
setContents("70" + "41" + "03" + "666F6F" + "21" + "7B" +
|
||||||
"41" + "03" + "666F6F" + "21" + "7B" + "80");
|
"41" + "03" + "626172" + "00" + "80");
|
||||||
BdfDictionary dictionary = r.readDictionary();
|
BdfDictionary dictionary = r.readDictionary();
|
||||||
assertEquals(2, dictionary.size());
|
assertEquals(2, dictionary.size());
|
||||||
assertTrue(dictionary.containsKey("foo"));
|
assertTrue(dictionary.containsKey("foo"));
|
||||||
@@ -590,6 +517,26 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
r.readDictionary();
|
r.readDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testReadDictionaryManually() throws Exception {
|
||||||
|
// A dictionary containing "foo" -> 123 and "bar" -> null
|
||||||
|
setContents("70" + "41" + "03" + "666F6F" + "21" + "7B" +
|
||||||
|
"41" + "03" + "626172" + "00" + "80");
|
||||||
|
r.readDictionaryStart();
|
||||||
|
assertFalse(r.hasDictionaryEnd());
|
||||||
|
assertEquals("foo", r.readString());
|
||||||
|
assertFalse(r.hasDictionaryEnd());
|
||||||
|
assertEquals(123, r.readLong());
|
||||||
|
assertFalse(r.hasDictionaryEnd());
|
||||||
|
assertEquals("bar", r.readString());
|
||||||
|
assertFalse(r.hasDictionaryEnd());
|
||||||
|
assertTrue(r.hasNull());
|
||||||
|
r.readNull();
|
||||||
|
assertTrue(r.hasDictionaryEnd());
|
||||||
|
r.readDictionaryEnd();
|
||||||
|
assertTrue(r.eof());
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testSkipDictionary() throws Exception {
|
public void testSkipDictionary() throws Exception {
|
||||||
// A map containing "foo" -> 123 and "bar" -> null
|
// A map containing "foo" -> 123 and "bar" -> null
|
||||||
@@ -610,10 +557,10 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
@Test
|
@Test
|
||||||
public void testNestedListWithinDepthLimit() throws Exception {
|
public void testNestedListWithinDepthLimit() throws Exception {
|
||||||
// A list containing a list containing a list containing a list...
|
// A list containing a list containing a list containing a list...
|
||||||
StringBuilder lists = new StringBuilder();
|
String lists = "";
|
||||||
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists.append("60");
|
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists += "60";
|
||||||
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists.append("80");
|
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) lists += "80";
|
||||||
setContents(lists.toString());
|
setContents(lists);
|
||||||
r.readList();
|
r.readList();
|
||||||
assertTrue(r.eof());
|
assertTrue(r.eof());
|
||||||
}
|
}
|
||||||
@@ -621,25 +568,23 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNestedListOutsideDepthLimit() throws Exception {
|
public void testNestedListOutsideDepthLimit() throws Exception {
|
||||||
// A list containing a list containing a list containing a list...
|
// A list containing a list containing a list containing a list...
|
||||||
StringBuilder lists = new StringBuilder();
|
String lists = "";
|
||||||
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists.append("60");
|
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists += "60";
|
||||||
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists.append("80");
|
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) lists += "80";
|
||||||
setContents(lists.toString());
|
setContents(lists);
|
||||||
r.readList();
|
r.readList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNestedDictionaryWithinDepthLimit() throws Exception {
|
public void testNestedDictionaryWithinDepthLimit() throws Exception {
|
||||||
// A dictionary containing a dictionary containing a dictionary...
|
// A dictionary containing a dictionary containing a dictionary...
|
||||||
StringBuilder dicts = new StringBuilder();
|
String dicts = "";
|
||||||
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) {
|
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++)
|
||||||
dicts.append("70").append("41").append("03").append("666F6F");
|
dicts += "70" + "41" + "03" + "666F6F";
|
||||||
}
|
dicts += "11";
|
||||||
dicts.append("11");
|
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++)
|
||||||
for (int i = 1; i <= DEFAULT_NESTED_LIMIT; i++) {
|
dicts += "80";
|
||||||
dicts.append("80");
|
setContents(dicts);
|
||||||
}
|
|
||||||
setContents(dicts.toString());
|
|
||||||
r.readDictionary();
|
r.readDictionary();
|
||||||
assertTrue(r.eof());
|
assertTrue(r.eof());
|
||||||
}
|
}
|
||||||
@@ -647,15 +592,13 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
@Test(expected = FormatException.class)
|
@Test(expected = FormatException.class)
|
||||||
public void testNestedDictionaryOutsideDepthLimit() throws Exception {
|
public void testNestedDictionaryOutsideDepthLimit() throws Exception {
|
||||||
// A dictionary containing a dictionary containing a dictionary...
|
// A dictionary containing a dictionary containing a dictionary...
|
||||||
StringBuilder dicts = new StringBuilder();
|
String dicts = "";
|
||||||
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) {
|
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++)
|
||||||
dicts.append("70").append("41").append("03").append("666F6F");
|
dicts += "70" + "41" + "03" + "666F6F";
|
||||||
}
|
dicts += "11";
|
||||||
dicts.append("11");
|
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++)
|
||||||
for (int i = 1; i <= DEFAULT_NESTED_LIMIT + 1; i++) {
|
dicts += "80";
|
||||||
dicts.append("80");
|
setContents(dicts);
|
||||||
}
|
|
||||||
setContents(dicts.toString());
|
|
||||||
r.readDictionary();
|
r.readDictionary();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,6 +625,6 @@ public class BdfReaderImplTest extends BrambleTestCase {
|
|||||||
private void setContents(String hex, int maxBufferSize)
|
private void setContents(String hex, int maxBufferSize)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
ByteArrayInputStream in = new ByteArrayInputStream(fromHexString(hex));
|
ByteArrayInputStream in = new ByteArrayInputStream(fromHexString(hex));
|
||||||
r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, maxBufferSize, true);
|
r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT, maxBufferSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,80 +0,0 @@
|
|||||||
package org.briarproject.bramble.data;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
|
||||||
import org.briarproject.bramble.api.data.BdfReader;
|
|
||||||
import org.briarproject.bramble.api.data.BdfWriter;
|
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.ByteArrayInputStream;
|
|
||||||
import java.io.ByteArrayOutputStream;
|
|
||||||
import java.io.InputStream;
|
|
||||||
import java.util.Iterator;
|
|
||||||
import java.util.LinkedHashMap;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.Map.Entry;
|
|
||||||
|
|
||||||
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_MAX_BUFFER_SIZE;
|
|
||||||
import static org.briarproject.bramble.api.data.BdfReader.DEFAULT_NESTED_LIMIT;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.fromHexString;
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.toHexString;
|
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertTrue;
|
|
||||||
|
|
||||||
public class BdfReaderWriterIntegrationTest extends BrambleTestCase {
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testConvertStringToCanonicalForm() throws Exception {
|
|
||||||
// 'foo' as a STRING_16 (not canonical, should be a STRING_8)
|
|
||||||
String hexIn = "42" + "0003" + "666F6F";
|
|
||||||
InputStream in = new ByteArrayInputStream(fromHexString(hexIn));
|
|
||||||
BdfReader r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
|
||||||
DEFAULT_MAX_BUFFER_SIZE, false); // Accept non-canonical
|
|
||||||
String s = r.readString();
|
|
||||||
assertEquals("foo", s);
|
|
||||||
assertTrue(r.eof());
|
|
||||||
// Convert the string back to BDF
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
BdfWriter w = new BdfWriterImpl(out);
|
|
||||||
w.writeString(s);
|
|
||||||
w.flush();
|
|
||||||
String hexOut = toHexString(out.toByteArray());
|
|
||||||
// The BDF should now be in canonical form
|
|
||||||
assertEquals("41" + "03" + "666F6F", hexOut);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testConvertDictionaryToCanonicalForm() throws Exception {
|
|
||||||
// A dictionary with keys in non-canonical order: 'foo' then 'bar'
|
|
||||||
String hexIn = "70" + "41" + "03" + "666F6F" + "21" + "01"
|
|
||||||
+ "41" + "03" + "626172" + "21" + "02" + "80";
|
|
||||||
InputStream in = new ByteArrayInputStream(fromHexString(hexIn));
|
|
||||||
BdfReader r = new BdfReaderImpl(in, DEFAULT_NESTED_LIMIT,
|
|
||||||
DEFAULT_MAX_BUFFER_SIZE, false); // Accept non-canonical
|
|
||||||
BdfDictionary d = r.readDictionary();
|
|
||||||
assertEquals(2, d.size());
|
|
||||||
assertTrue(r.eof());
|
|
||||||
// The entries should be returned in canonical order
|
|
||||||
Iterator<Entry<String, Object>> it = d.entrySet().iterator();
|
|
||||||
Entry<String, Object> first = it.next();
|
|
||||||
assertEquals("bar", first.getKey());
|
|
||||||
assertEquals(2L, first.getValue());
|
|
||||||
Entry<String, Object> second = it.next();
|
|
||||||
assertEquals("foo", second.getKey());
|
|
||||||
assertEquals(1L, second.getValue());
|
|
||||||
|
|
||||||
// Convert a non-canonical map to BDF (use LinkedHashMap so we know
|
|
||||||
// the entries will be iterated over in non-canonical order)
|
|
||||||
Map<String, Object> m = new LinkedHashMap<>();
|
|
||||||
m.put("foo", 1);
|
|
||||||
m.put("bar", 2);
|
|
||||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
|
||||||
BdfWriter w = new BdfWriterImpl(out);
|
|
||||||
w.writeDictionary(m);
|
|
||||||
w.flush();
|
|
||||||
String hexOut = toHexString(out.toByteArray());
|
|
||||||
// The entries should be in canonical order: 'bar' then 'foo'
|
|
||||||
assertEquals("70" + "41" + "03" + "626172" + "21" + "02"
|
|
||||||
+ "41" + "03" + "666F6F" + "21" + "01" + "80", hexOut);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.bramble.data;
|
package org.briarproject.bramble.data;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
|
||||||
import org.briarproject.bramble.test.BrambleTestCase;
|
import org.briarproject.bramble.test.BrambleTestCase;
|
||||||
import org.briarproject.bramble.util.StringUtils;
|
import org.briarproject.bramble.util.StringUtils;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
@@ -169,11 +168,9 @@ public class BdfWriterImplTest extends BrambleTestCase {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWriteDictionary() throws IOException {
|
public void testWriteDictionary() throws IOException {
|
||||||
// Add entries to dictionary in descending order - they should be
|
// Use LinkedHashMap to get predictable iteration order
|
||||||
// output in ascending order. Use LinkedHashMap to get predictable
|
|
||||||
// iteration order
|
|
||||||
Map<String, Object> m = new LinkedHashMap<>();
|
Map<String, Object> m = new LinkedHashMap<>();
|
||||||
for (int i = 3; i >= 0; i--) m.put(String.valueOf(i), i);
|
for (int i = 0; i < 4; i++) m.put(String.valueOf(i), i);
|
||||||
w.writeDictionary(m);
|
w.writeDictionary(m);
|
||||||
// DICTIONARY tag, keys as strings and values as integers, END tag
|
// DICTIONARY tag, keys as strings and values as integers, END tag
|
||||||
checkContents("70" + "41" + "01" + "30" + "21" + "00" +
|
checkContents("70" + "41" + "01" + "30" + "21" + "00" +
|
||||||
@@ -183,17 +180,30 @@ public class BdfWriterImplTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWriteBdfDictionary() throws IOException {
|
public void testWriteDelimitedList() throws IOException {
|
||||||
// Add entries to dictionary in descending order - they should be
|
w.writeListStart();
|
||||||
// output in ascending order
|
w.writeLong(1);
|
||||||
BdfDictionary d = new BdfDictionary();
|
w.writeString("foo");
|
||||||
for (int i = 3; i >= 0; i--) d.put(String.valueOf(i), i);
|
w.writeLong(128);
|
||||||
w.writeDictionary(d);
|
w.writeListEnd();
|
||||||
// DICTIONARY tag, keys as strings and values as integers, END tag
|
// LIST tag, 1 as integer, "foo" as string, 128 as integer, END tag
|
||||||
checkContents("70" + "41" + "01" + "30" + "21" + "00" +
|
checkContents("60" + "21" + "01" +
|
||||||
"41" + "01" + "31" + "21" + "01" +
|
"41" + "03" + "666F6F" +
|
||||||
"41" + "01" + "32" + "21" + "02" +
|
"22" + "0080" + "80");
|
||||||
"41" + "01" + "33" + "21" + "03" + "80");
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testWriteDelimitedDictionary() throws IOException {
|
||||||
|
w.writeDictionaryStart();
|
||||||
|
w.writeString("foo");
|
||||||
|
w.writeLong(123);
|
||||||
|
w.writeString("bar");
|
||||||
|
w.writeNull();
|
||||||
|
w.writeDictionaryEnd();
|
||||||
|
// DICTIONARY tag, "foo" as string, 123 as integer, "bar" as string,
|
||||||
|
// NULL tag, END tag
|
||||||
|
checkContents("70" + "41" + "03" + "666F6F" +
|
||||||
|
"21" + "7B" + "41" + "03" + "626172" + "00" + "80");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
package org.briarproject.bramble.mailbox;
|
package org.briarproject.bramble.mailbox;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.FormatException;
|
|
||||||
import org.briarproject.bramble.api.db.DbException;
|
import org.briarproject.bramble.api.db.DbException;
|
||||||
import org.briarproject.bramble.api.db.Transaction;
|
import org.briarproject.bramble.api.db.Transaction;
|
||||||
import org.briarproject.bramble.api.db.TransactionManager;
|
import org.briarproject.bramble.api.db.TransactionManager;
|
||||||
@@ -10,23 +9,17 @@ import org.briarproject.bramble.api.mailbox.event.OwnMailboxConnectionStatusEven
|
|||||||
import org.briarproject.bramble.api.system.Clock;
|
import org.briarproject.bramble.api.system.Clock;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
import org.briarproject.bramble.test.DbExpectations;
|
import org.briarproject.bramble.test.DbExpectations;
|
||||||
import org.briarproject.bramble.util.Base32;
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.Locale;
|
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
|
|
||||||
import static org.briarproject.bramble.util.StringUtils.ISO_8859_1;
|
|
||||||
import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS;
|
import static org.briarproject.bramble.api.mailbox.MailboxConstants.CLIENT_SUPPORTS;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getMailboxProperties;
|
import static org.briarproject.bramble.test.TestUtils.getMailboxProperties;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
|
||||||
import static org.briarproject.bramble.test.TestUtils.hasEvent;
|
import static org.briarproject.bramble.test.TestUtils.hasEvent;
|
||||||
import static org.junit.Assert.assertEquals;
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import static org.junit.Assert.assertFalse;
|
||||||
import static org.junit.Assert.assertTrue;
|
import static org.junit.Assert.assertTrue;
|
||||||
import static org.junit.Assert.fail;
|
|
||||||
|
|
||||||
public class MailboxManagerImplTest extends BrambleMockTestCase {
|
public class MailboxManagerImplTest extends BrambleMockTestCase {
|
||||||
|
|
||||||
@@ -132,32 +125,4 @@ public class MailboxManagerImplTest extends BrambleMockTestCase {
|
|||||||
assertTrue(manager.checkConnection());
|
assertTrue(manager.checkConnection());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testConvertBase32Payload() throws FormatException {
|
|
||||||
byte[] payload = getRandomBytes(65);
|
|
||||||
String base32payload = Base32.encode(payload).toLowerCase(Locale.ROOT);
|
|
||||||
String expected = new String(payload, ISO_8859_1);
|
|
||||||
try {
|
|
||||||
manager.convertBase32Payload("foo bar");
|
|
||||||
fail();
|
|
||||||
} catch (FormatException e) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
try { // doesn't work with shorter link
|
|
||||||
manager.convertBase32Payload("briar-mailbox://" +
|
|
||||||
base32payload.substring(0, base32payload.length() - 1));
|
|
||||||
fail();
|
|
||||||
} catch (FormatException e) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
// works with white-spaces
|
|
||||||
assertEquals(expected, manager.convertBase32Payload(
|
|
||||||
"foo bar briar-mailbox://" + base32payload + " foo bar"));
|
|
||||||
// even works without white-space at the end
|
|
||||||
assertEquals(expected, manager.convertBase32Payload(
|
|
||||||
"foo bar briar-mailbox://" + base32payload + "foobar"));
|
|
||||||
// even works without schema and extra chars at end
|
|
||||||
assertEquals(expected, manager.convertBase32Payload(
|
|
||||||
"foo bar " + base32payload + "foobar"));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -217,13 +217,13 @@ public class LanTcpPluginTest extends BrambleTestCase {
|
|||||||
// The plugin should have bound a socket and stored the port number
|
// The plugin should have bound a socket and stored the port number
|
||||||
BdfList descriptor = kal.getDescriptor();
|
BdfList descriptor = kal.getDescriptor();
|
||||||
assertEquals(3, descriptor.size());
|
assertEquals(3, descriptor.size());
|
||||||
assertEquals(TRANSPORT_ID_LAN, descriptor.getInt(0).intValue());
|
assertEquals(TRANSPORT_ID_LAN, descriptor.getLong(0).longValue());
|
||||||
byte[] address = descriptor.getRaw(1);
|
byte[] address = descriptor.getRaw(1);
|
||||||
InetAddress addr = InetAddress.getByAddress(address);
|
InetAddress addr = InetAddress.getByAddress(address);
|
||||||
assertTrue(addr instanceof Inet4Address);
|
assertTrue(addr instanceof Inet4Address);
|
||||||
assertFalse(addr.isLoopbackAddress());
|
assertFalse(addr.isLoopbackAddress());
|
||||||
assertTrue(addr.isLinkLocalAddress() || addr.isSiteLocalAddress());
|
assertTrue(addr.isLinkLocalAddress() || addr.isSiteLocalAddress());
|
||||||
int port = descriptor.getInt(2);
|
int port = descriptor.getLong(2).intValue();
|
||||||
assertTrue(port > 0 && port < 65536);
|
assertTrue(port > 0 && port < 65536);
|
||||||
// The plugin should be listening on the port
|
// The plugin should be listening on the port
|
||||||
InetSocketAddress socketAddr = new InetSocketAddress(addr, port);
|
InetSocketAddress socketAddr = new InetSocketAddress(addr, port);
|
||||||
|
|||||||
@@ -404,7 +404,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, fooUpdateId, false);
|
oneOf(clientHelper).getMessageAsList(txn, fooUpdateId);
|
||||||
will(returnValue(fooUpdate));
|
will(returnValue(fooUpdate));
|
||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
fooPropertiesDict);
|
fooPropertiesDict);
|
||||||
@@ -471,7 +471,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
contactGroup2.getId());
|
contactGroup2.getId());
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, fooUpdateId, false);
|
oneOf(clientHelper).getMessageAsList(txn, fooUpdateId);
|
||||||
will(returnValue(fooUpdate));
|
will(returnValue(fooUpdate));
|
||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
fooPropertiesDict);
|
fooPropertiesDict);
|
||||||
@@ -526,7 +526,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
contactGroup.getId());
|
contactGroup.getId());
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, updateId, false);
|
oneOf(clientHelper).getMessageAsList(txn, updateId);
|
||||||
will(returnValue(update));
|
will(returnValue(update));
|
||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
fooPropertiesDict);
|
fooPropertiesDict);
|
||||||
@@ -564,7 +564,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, updateId, false);
|
oneOf(clientHelper).getMessageAsList(txn, updateId);
|
||||||
will(returnValue(update));
|
will(returnValue(update));
|
||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
fooPropertiesDict);
|
fooPropertiesDict);
|
||||||
@@ -695,8 +695,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
will(returnValue(localGroupMessageMetadata));
|
will(returnValue(localGroupMessageMetadata));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId,
|
oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId);
|
||||||
false);
|
|
||||||
will(returnValue(oldUpdate));
|
will(returnValue(oldUpdate));
|
||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
oldPropertiesDict);
|
oldPropertiesDict);
|
||||||
@@ -761,8 +760,7 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
oneOf(clientHelper).getMessageMetadataAsDictionary(txn,
|
||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
will(returnValue(localGroupMessageMetadata));
|
will(returnValue(localGroupMessageMetadata));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId,
|
oneOf(clientHelper).getMessageAsList(txn, localGroupUpdateId);
|
||||||
false);
|
|
||||||
will(returnValue(oldUpdate));
|
will(returnValue(oldUpdate));
|
||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
oldPropertiesDict);
|
oldPropertiesDict);
|
||||||
@@ -821,12 +819,12 @@ public class TransportPropertyManagerImplTest extends BrambleMockTestCase {
|
|||||||
localGroup.getId());
|
localGroup.getId());
|
||||||
will(returnValue(messageMetadata));
|
will(returnValue(messageMetadata));
|
||||||
// Retrieve and parse the latest local properties
|
// Retrieve and parse the latest local properties
|
||||||
oneOf(clientHelper).getMessageAsList(txn, fooVersion999, false);
|
oneOf(clientHelper).getMessageAsList(txn, fooVersion999);
|
||||||
will(returnValue(fooUpdate));
|
will(returnValue(fooUpdate));
|
||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
fooPropertiesDict);
|
fooPropertiesDict);
|
||||||
will(returnValue(fooProperties));
|
will(returnValue(fooProperties));
|
||||||
oneOf(clientHelper).getMessageAsList(txn, barVersion3, false);
|
oneOf(clientHelper).getMessageAsList(txn, barVersion3);
|
||||||
will(returnValue(barUpdate));
|
will(returnValue(barUpdate));
|
||||||
oneOf(clientHelper).parseAndValidateTransportProperties(
|
oneOf(clientHelper).parseAndValidateTransportProperties(
|
||||||
barPropertiesDict);
|
barPropertiesDict);
|
||||||
|
|||||||
@@ -6,18 +6,13 @@ import org.briarproject.bramble.api.UniqueId;
|
|||||||
import org.briarproject.bramble.api.record.Record;
|
import org.briarproject.bramble.api.record.Record;
|
||||||
import org.briarproject.bramble.api.record.RecordReader;
|
import org.briarproject.bramble.api.record.RecordReader;
|
||||||
import org.briarproject.bramble.api.sync.Ack;
|
import org.briarproject.bramble.api.sync.Ack;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
|
||||||
import org.briarproject.bramble.api.sync.Message;
|
|
||||||
import org.briarproject.bramble.api.sync.MessageFactory;
|
import org.briarproject.bramble.api.sync.MessageFactory;
|
||||||
import org.briarproject.bramble.api.sync.MessageId;
|
|
||||||
import org.briarproject.bramble.api.sync.Offer;
|
import org.briarproject.bramble.api.sync.Offer;
|
||||||
import org.briarproject.bramble.api.sync.Priority;
|
import org.briarproject.bramble.api.sync.Priority;
|
||||||
import org.briarproject.bramble.api.sync.Request;
|
import org.briarproject.bramble.api.sync.Request;
|
||||||
import org.briarproject.bramble.api.sync.SyncRecordReader;
|
import org.briarproject.bramble.api.sync.SyncRecordReader;
|
||||||
import org.briarproject.bramble.api.sync.Versions;
|
import org.briarproject.bramble.api.sync.Versions;
|
||||||
import org.briarproject.bramble.test.BrambleMockTestCase;
|
import org.briarproject.bramble.test.BrambleMockTestCase;
|
||||||
import org.briarproject.bramble.test.PredicateMatcher;
|
|
||||||
import org.hamcrest.Matcher;
|
|
||||||
import org.jmock.Expectations;
|
import org.jmock.Expectations;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
@@ -28,15 +23,12 @@ import javax.annotation.Nullable;
|
|||||||
|
|
||||||
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
import static org.briarproject.bramble.api.record.Record.MAX_RECORD_PAYLOAD_BYTES;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
|
import static org.briarproject.bramble.api.sync.RecordTypes.ACK;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.MESSAGE;
|
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
import static org.briarproject.bramble.api.sync.RecordTypes.OFFER;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.PRIORITY;
|
import static org.briarproject.bramble.api.sync.RecordTypes.PRIORITY;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
import static org.briarproject.bramble.api.sync.RecordTypes.REQUEST;
|
||||||
import static org.briarproject.bramble.api.sync.RecordTypes.VERSIONS;
|
import static org.briarproject.bramble.api.sync.RecordTypes.VERSIONS;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_BODY_LENGTH;
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_MESSAGE_IDS;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_SUPPORTED_VERSIONS;
|
import static org.briarproject.bramble.api.sync.SyncConstants.MAX_SUPPORTED_VERSIONS;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
|
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.PRIORITY_NONCE_BYTES;
|
import static org.briarproject.bramble.api.sync.SyncConstants.PRIORITY_NONCE_BYTES;
|
||||||
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
import static org.briarproject.bramble.api.sync.SyncConstants.PROTOCOL_VERSION;
|
||||||
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
import static org.briarproject.bramble.test.TestUtils.getRandomBytes;
|
||||||
@@ -54,38 +46,6 @@ public class SyncRecordReaderImplTest extends BrambleMockTestCase {
|
|||||||
private final SyncRecordReader reader =
|
private final SyncRecordReader reader =
|
||||||
new SyncRecordReaderImpl(messageFactory, recordReader);
|
new SyncRecordReaderImpl(messageFactory, recordReader);
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoFormatExceptionIfMessageIsMinimumSize() throws Exception {
|
|
||||||
expectReadRecord(createMessage(MESSAGE_HEADER_LENGTH + 1));
|
|
||||||
expectCreateMessage(1);
|
|
||||||
|
|
||||||
reader.readMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testFormatExceptionIfMessageIsTooSmall() throws Exception {
|
|
||||||
expectReadRecord(createMessage(MESSAGE_HEADER_LENGTH));
|
|
||||||
|
|
||||||
reader.readMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testNoFormatExceptionIfMessageIsMaximumSize() throws Exception {
|
|
||||||
expectReadRecord(createMessage(MESSAGE_HEADER_LENGTH
|
|
||||||
+ MAX_MESSAGE_BODY_LENGTH));
|
|
||||||
expectCreateMessage(MAX_MESSAGE_BODY_LENGTH);
|
|
||||||
|
|
||||||
reader.readMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
|
||||||
public void testFormatExceptionIfMessageIsTooLarge() throws Exception {
|
|
||||||
expectReadRecord(createMessage(MESSAGE_HEADER_LENGTH
|
|
||||||
+ MAX_MESSAGE_BODY_LENGTH + 1));
|
|
||||||
|
|
||||||
reader.readMessage();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception {
|
public void testNoFormatExceptionIfAckIsMaximumSize() throws Exception {
|
||||||
expectReadRecord(createAck());
|
expectReadRecord(createAck());
|
||||||
@@ -198,20 +158,6 @@ public class SyncRecordReaderImplTest extends BrambleMockTestCase {
|
|||||||
assertTrue(reader.eof());
|
assertTrue(reader.eof());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void expectCreateMessage(int bodyLength) {
|
|
||||||
MessageId messageId = new MessageId(getRandomId());
|
|
||||||
GroupId groupId = new GroupId(getRandomId());
|
|
||||||
long timestamp = System.currentTimeMillis();
|
|
||||||
|
|
||||||
context.checking(new Expectations() {{
|
|
||||||
Matcher<byte[]> matcher = new PredicateMatcher<>(byte[].class,
|
|
||||||
b -> b.length == MESSAGE_HEADER_LENGTH + bodyLength);
|
|
||||||
oneOf(messageFactory).createMessage(with(matcher));
|
|
||||||
will(returnValue(new Message(messageId, groupId, timestamp,
|
|
||||||
new byte[bodyLength])));
|
|
||||||
}});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void expectReadRecord(@Nullable Record record) throws Exception {
|
private void expectReadRecord(@Nullable Record record) throws Exception {
|
||||||
context.checking(new Expectations() {{
|
context.checking(new Expectations() {{
|
||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
@@ -221,10 +167,6 @@ public class SyncRecordReaderImplTest extends BrambleMockTestCase {
|
|||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
|
||||||
private Record createMessage(int payloadLength) {
|
|
||||||
return new Record(PROTOCOL_VERSION, MESSAGE, new byte[payloadLength]);
|
|
||||||
}
|
|
||||||
|
|
||||||
private Record createAck() throws Exception {
|
private Record createAck() throws Exception {
|
||||||
return new Record(PROTOCOL_VERSION, ACK, createPayload());
|
return new Record(PROTOCOL_VERSION, ACK, createPayload());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -88,58 +88,51 @@ public class StringUtilsTest extends BrambleTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFromUtf8AcceptsNullCharacterUsingStandardUtf8()
|
public void testFromUtf8AcceptsNullCharacterUsingStandardUtf8() {
|
||||||
throws Exception {
|
|
||||||
// The UTF-8 encoding of the null character is valid
|
// The UTF-8 encoding of the null character is valid
|
||||||
byte[] utf8 = new byte[1];
|
assertEquals("\u0000", StringUtils.fromUtf8(new byte[1]));
|
||||||
String actual = StringUtils.fromUtf8(utf8);
|
|
||||||
assertEquals("\u0000", actual);
|
|
||||||
// When we convert back to UTF-8 we should get the original encoding
|
|
||||||
assertArrayEquals(utf8, StringUtils.toUtf8(actual));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test
|
||||||
public void testFromUtf8RejectsNullCharacterUsingModifiedUtf8()
|
public void testFromUtf8RemovesNullCharacterUsingModifiedUtf8() {
|
||||||
throws Exception {
|
|
||||||
// The modified UTF-8 encoding of the null character is not valid
|
// The modified UTF-8 encoding of the null character is not valid
|
||||||
byte[] b = new byte[] {
|
byte[] b = new byte[] {
|
||||||
(byte) 0xC0, (byte) 0x80, // Null character as modified UTF-8
|
(byte) 0xC0, (byte) 0x80, // Null character as modified UTF-8
|
||||||
(byte) 0xC8, (byte) 0x85 // U+0205
|
(byte) 0xC8, (byte) 0x85 // U+0205
|
||||||
};
|
};
|
||||||
StringUtils.fromUtf8(b);
|
// Conversion should ignore the invalid character and return the rest
|
||||||
|
String expected = "\u0205";
|
||||||
|
assertEquals(expected, StringUtils.fromUtf8(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFromUtf8AcceptsSupplementaryCharacterUsingStandardUtf8()
|
public void testFromUtf8AcceptsSupplementaryCharacterUsingStandardUtf8() {
|
||||||
throws Exception {
|
|
||||||
// The UTF-8 encoding of a supplementary character is valid and should
|
// The UTF-8 encoding of a supplementary character is valid and should
|
||||||
// be converted to a surrogate pair
|
// be converted to a surrogate pair
|
||||||
byte[] utf8 = new byte[] {
|
byte[] b = new byte[] {
|
||||||
(byte) 0xF0, (byte) 0x90, (byte) 0x90, (byte) 0x80, // U+10400
|
(byte) 0xF0, (byte) 0x90, (byte) 0x90, (byte) 0x80, // U+10400
|
||||||
(byte) 0xC8, (byte) 0x85 // U+0205
|
(byte) 0xC8, (byte) 0x85 // U+0205
|
||||||
};
|
};
|
||||||
String expected = "\uD801\uDC00\u0205"; // Surrogate pair
|
String expected = "\uD801\uDC00\u0205"; // Surrogate pair
|
||||||
String actual = StringUtils.fromUtf8(utf8);
|
assertEquals(expected, StringUtils.fromUtf8(b));
|
||||||
assertEquals(expected, actual);
|
|
||||||
// When we convert back to UTF-8 we should get the original encoding
|
|
||||||
assertArrayEquals(utf8, StringUtils.toUtf8(actual));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test(expected = FormatException.class)
|
@Test
|
||||||
public void testFromUtf8RejectsSupplementaryCharacterUsingModifiedUtf8()
|
public void testFromUtf8RemovesSupplementaryCharacterUsingModifiedUtf8() {
|
||||||
throws Exception {
|
|
||||||
// The CESU-8 or modified UTF-8 encoding of a supplementary character
|
// The CESU-8 or modified UTF-8 encoding of a supplementary character
|
||||||
// is not valid
|
// is not valid
|
||||||
byte[] utf8 = new byte[] {
|
byte[] b = new byte[] {
|
||||||
(byte) 0xED, (byte) 0xA0, (byte) 0x81, // U+10400 as CSEU-8
|
(byte) 0xED, (byte) 0xA0, (byte) 0x81, // U+10400 as CSEU-8
|
||||||
(byte) 0xED, (byte) 0xB0, (byte) 0x80,
|
(byte) 0xED, (byte) 0xB0, (byte) 0x80,
|
||||||
(byte) 0xC8, (byte) 0x85 // U+0205
|
(byte) 0xC8, (byte) 0x85 // U+0205
|
||||||
};
|
};
|
||||||
StringUtils.fromUtf8(utf8);
|
// Conversion should ignore the invalid character and return the rest
|
||||||
|
String expected = "\u0205";
|
||||||
|
assertEquals(expected, StringUtils.fromUtf8(b));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testFromUtf8EmptyInput() throws Exception {
|
public void testFromUtf8EmptyInput() {
|
||||||
assertEquals("", StringUtils.fromUtf8(new byte[0]));
|
assertEquals("", StringUtils.fromUtf8(new byte[0]));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,10 @@ apply plugin: 'witness'
|
|||||||
apply from: 'witness.gradle'
|
apply from: 'witness.gradle'
|
||||||
apply from: '../dagger.gradle'
|
apply from: '../dagger.gradle'
|
||||||
|
|
||||||
|
configurations {
|
||||||
|
tor
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation project(':bramble-core')
|
implementation project(':bramble-core')
|
||||||
|
|
||||||
@@ -15,9 +19,12 @@ dependencies {
|
|||||||
implementation "net.java.dev.jna:jna:$jna_version"
|
implementation "net.java.dev.jna:jna:$jna_version"
|
||||||
implementation "net.java.dev.jna:jna-platform:$jna_version"
|
implementation "net.java.dev.jna:jna-platform:$jna_version"
|
||||||
|
|
||||||
testImplementation "org.briarproject:tor-linux:$tor_version"
|
tor "org.briarproject:tor-linux:$tor_version"
|
||||||
testImplementation "org.briarproject:obfs4proxy-linux:$obfs4proxy_version"
|
tor "org.briarproject:tor-windows:$tor_version"
|
||||||
testImplementation "org.briarproject:snowflake-linux:$snowflake_version"
|
tor "org.briarproject:obfs4proxy-linux:$obfs4proxy_version"
|
||||||
|
tor "org.briarproject:obfs4proxy-windows:$obfs4proxy_version"
|
||||||
|
tor "org.briarproject:snowflake-linux:$snowflake_version"
|
||||||
|
tor "org.briarproject:snowflake-windows:$snowflake_version"
|
||||||
|
|
||||||
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
annotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||||
|
|
||||||
@@ -32,6 +39,31 @@ dependencies {
|
|||||||
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
testAnnotationProcessor "com.google.dagger:dagger-compiler:$dagger_version"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def torBinariesDir = 'src/main/resources'
|
||||||
|
|
||||||
|
task cleanTorBinaries {
|
||||||
|
doLast {
|
||||||
|
delete fileTree(torBinariesDir) { include '*.zip' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
clean.dependsOn cleanTorBinaries
|
||||||
|
|
||||||
|
task unpackTorBinaries {
|
||||||
|
doLast {
|
||||||
|
copy {
|
||||||
|
from configurations.tor.collect { zipTree(it) }
|
||||||
|
into torBinariesDir
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dependsOn cleanTorBinaries
|
||||||
|
}
|
||||||
|
|
||||||
|
processResources {
|
||||||
|
inputs.dir torBinariesDir
|
||||||
|
dependsOn unpackTorBinaries
|
||||||
|
}
|
||||||
|
|
||||||
tasks.withType(Test) {
|
tasks.withType(Test) {
|
||||||
systemProperty 'java.library.path', 'libs'
|
systemProperty 'java.library.path', 'libs'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,9 +62,9 @@ public class UnixTorPluginFactory extends TorPluginFactory {
|
|||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("System's os.arch is " + arch);
|
LOG.info("System's os.arch is " + arch);
|
||||||
}
|
}
|
||||||
if (arch.equals("amd64")) return "x86_64";
|
if (arch.equals("amd64")) return "linux-x86_64";
|
||||||
else if (arch.equals("aarch64")) return "aarch64";
|
else if (arch.equals("aarch64")) return "linux-aarch64";
|
||||||
else if (arch.equals("arm")) return "armhf";
|
else if (arch.equals("arm")) return "linux-armhf";
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -94,8 +94,4 @@ class WindowsTorPlugin extends JavaTorPlugin {
|
|||||||
if (!success.take()) throw new PluginException();
|
if (!success.take()) throw new PluginException();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected String getExecutableExtension() {
|
|
||||||
return ".exe";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,7 +62,7 @@ public class WindowsTorPluginFactory extends TorPluginFactory {
|
|||||||
if (LOG.isLoggable(INFO)) {
|
if (LOG.isLoggable(INFO)) {
|
||||||
LOG.info("System's os.arch is " + arch);
|
LOG.info("System's os.arch is " + arch);
|
||||||
}
|
}
|
||||||
if (arch.equals("amd64")) return "x86_64";
|
if (arch.equals("amd64")) return "windows-x86_64";
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package org.briarproject.bramble.test;
|
|
||||||
|
|
||||||
import org.briarproject.bramble.util.OsUtils;
|
|
||||||
import org.junit.Before;
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import java.io.InputStream;
|
|
||||||
|
|
||||||
import static org.junit.Assert.assertNotNull;
|
|
||||||
import static org.junit.Assume.assumeTrue;
|
|
||||||
|
|
||||||
public class TestResources {
|
|
||||||
|
|
||||||
@Before
|
|
||||||
public void isRunningOnLinux() {
|
|
||||||
assumeTrue(OsUtils.isLinux());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canReadTorLinux() {
|
|
||||||
InputStream input = Thread.currentThread().getContextClassLoader()
|
|
||||||
.getResourceAsStream("x86_64/tor");
|
|
||||||
assertNotNull(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canReadObfs4ProxyLinux() {
|
|
||||||
InputStream input = Thread.currentThread().getContextClassLoader()
|
|
||||||
.getResourceAsStream("x86_64/obfs4proxy");
|
|
||||||
assertNotNull(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void canReadSnowflakeLinux() {
|
|
||||||
InputStream input = Thread.currentThread().getContextClassLoader()
|
|
||||||
.getResourceAsStream("x86_64/snowflake");
|
|
||||||
assertNotNull(input);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -26,9 +26,12 @@ dependencyVerification {
|
|||||||
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
'net.jcip:jcip-annotations:1.0:jcip-annotations-1.0.jar:be5805392060c71474bf6c9a67a099471274d30b83eef84bfc4e0889a4f1dcc0',
|
||||||
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
'net.ltgt.gradle.incap:incap:0.2:incap-0.2.jar:b625b9806b0f1e4bc7a2e3457119488de3cd57ea20feedd513db070a573a4ffd',
|
||||||
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
'org.apache-extras.beanshell:bsh:2.0b6:bsh-2.0b6.jar:a17955976070c0573235ee662f2794a78082758b61accffce8d3f8aedcd91047',
|
||||||
'org.briarproject:obfs4proxy-linux:0.0.14-tor2:obfs4proxy-linux-0.0.14-tor2.jar:bb2431092b5ad998ad620b0223e725c0f7e43f1b02af2f097a2544edc1fd9738',
|
'org.briarproject:obfs4proxy-linux:0.0.14-tor1:obfs4proxy-linux-0.0.14-tor1.jar:9783b9c7ec588a5246f534a9c5782783c8c9821825f81c3e0c6f1ecee61cfcbb',
|
||||||
'org.briarproject:snowflake-linux:2.5.1:snowflake-linux-2.5.1.jar:edc807dcb7758365970d95525e4749349a27f462d0e2df6505ad1ca65fb296d2',
|
'org.briarproject:obfs4proxy-windows:0.0.14-tor1:obfs4proxy-windows-0.0.14-tor1.jar:9dd122b31b3cd1616f168091dcdb01de049d1e052fe5c089b7627618a8a2694b',
|
||||||
'org.briarproject:tor-linux:0.4.7.13-2:tor-linux-0.4.7.13-2.jar:1e4ca9e0f724e1f17fcce570832704942cc3be26c4c2eccbe5aae29f35afa307',
|
'org.briarproject:snowflake-linux:2.3.1:snowflake-linux-2.3.1.jar:99ecf4546d8f79eb8408168c09380fec596558ac934554bf7d4247ea7ef2c9f3',
|
||||||
|
'org.briarproject:snowflake-windows:2.3.1:snowflake-windows-2.3.1.jar:d011f1a72c00a221f56380c19aad8ff11db8c2bb1adb0784125572d80b4d275a',
|
||||||
|
'org.briarproject:tor-linux:0.4.7.13:tor-linux-0.4.7.13.jar:9819ee973cbcdc133f7d04aef9d4b957a35087627a790e532142d15412a9636f',
|
||||||
|
'org.briarproject:tor-windows:0.4.7.13:tor-windows-0.4.7.13.jar:853d2769665614e26703cbe02e43b218b064c04a0bcd120fdc459cda45bd2606',
|
||||||
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
|
'org.checkerframework:checker-compat-qual:2.5.5:checker-compat-qual-2.5.5.jar:11d134b245e9cacc474514d2d66b5b8618f8039a1465cdc55bbc0b34e0008b7a',
|
||||||
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
|
'org.checkerframework:checker-qual:3.12.0:checker-qual-3.12.0.jar:ff10785ac2a357ec5de9c293cb982a2cbb605c0309ea4cc1cb9b9bc6dbe7f3cb',
|
||||||
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
'org.hamcrest:hamcrest-core:2.1:hamcrest-core-2.1.jar:e09109e54a289d88506b9bfec987ddd199f4217c9464132668351b9a4f00bee9',
|
||||||
|
|||||||
@@ -26,8 +26,8 @@ android {
|
|||||||
defaultConfig {
|
defaultConfig {
|
||||||
minSdkVersion 16
|
minSdkVersion 16
|
||||||
targetSdkVersion 31
|
targetSdkVersion 31
|
||||||
versionCode 10423
|
versionCode 10420
|
||||||
versionName "1.4.23"
|
versionName "1.4.20"
|
||||||
applicationId "org.briarproject.briar.android"
|
applicationId "org.briarproject.briar.android"
|
||||||
buildConfigField "String", "TorVersion", "\"$tor_version\""
|
buildConfigField "String", "TorVersion", "\"$tor_version\""
|
||||||
|
|
||||||
|
|||||||
@@ -5,25 +5,16 @@ import android.os.Bundle;
|
|||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.activity.BriarActivity;
|
import org.briarproject.briar.android.activity.BriarActivity;
|
||||||
import org.briarproject.briar.android.blog.RssImportResult.FileImportError;
|
|
||||||
import org.briarproject.briar.android.blog.RssImportResult.FileImportSuccess;
|
|
||||||
import org.briarproject.briar.android.blog.RssImportResult.UrlImportError;
|
|
||||||
import org.briarproject.briar.android.blog.RssImportResult.UrlImportSuccess;
|
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
import org.briarproject.briar.android.fragment.BaseFragment.BaseFragmentListener;
|
||||||
import org.briarproject.briar.android.fragment.ErrorFragment;
|
|
||||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.fragment.app.FragmentManager;
|
import androidx.fragment.app.FragmentManager;
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import static androidx.fragment.app.FragmentManager.POP_BACK_STACK_INCLUSIVE;
|
|
||||||
import static org.briarproject.briar.android.util.UiUtils.showFragment;
|
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
public class RssFeedActivity extends BriarActivity
|
public class RssFeedActivity extends BriarActivity
|
||||||
@@ -54,29 +45,21 @@ public class RssFeedActivity extends BriarActivity
|
|||||||
viewModel.getImportResult().observeEvent(this, this::onImportResult);
|
viewModel.getImportResult().observeEvent(this, this::onImportResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onImportResult(@Nullable RssImportResult result) {
|
private void onImportResult(boolean result) {
|
||||||
FragmentManager fm = getSupportFragmentManager();
|
if (result) {
|
||||||
if (result instanceof UrlImportSuccess) {
|
FragmentManager fm = getSupportFragmentManager();
|
||||||
if (fm.findFragmentByTag(RssFeedImportFragment.TAG) != null) {
|
if (fm.findFragmentByTag(RssFeedImportFragment.TAG) != null) {
|
||||||
onBackPressed();
|
onBackPressed();
|
||||||
}
|
}
|
||||||
} else if (result instanceof UrlImportError) {
|
} else {
|
||||||
String url = ((UrlImportError) result).url;
|
String url = viewModel.getUrlFailedImport();
|
||||||
|
if (url == null) {
|
||||||
|
throw new AssertionError();
|
||||||
|
}
|
||||||
RssFeedImportFailedDialogFragment dialog =
|
RssFeedImportFailedDialogFragment dialog =
|
||||||
RssFeedImportFailedDialogFragment.newInstance(url);
|
RssFeedImportFailedDialogFragment.newInstance(url);
|
||||||
dialog.show(fm, RssFeedImportFailedDialogFragment.TAG);
|
dialog.show(getSupportFragmentManager(),
|
||||||
} else if (result instanceof FileImportSuccess) {
|
RssFeedImportFailedDialogFragment.TAG);
|
||||||
// pop stack back to before the initial import fragment
|
|
||||||
fm.popBackStackImmediate(RssFeedImportFragment.TAG,
|
|
||||||
POP_BACK_STACK_INCLUSIVE);
|
|
||||||
} else if (result instanceof FileImportError) {
|
|
||||||
// pop stack back to initial import fragment
|
|
||||||
fm.popBackStackImmediate(RssFeedImportFragment.TAG, 0);
|
|
||||||
// show error fragment
|
|
||||||
Fragment f = ErrorFragment.newInstance(
|
|
||||||
getString(R.string.blogs_rss_feeds_import_error));
|
|
||||||
String tag = ErrorFragment.TAG;
|
|
||||||
showFragment(fm, f, tag);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,9 @@
|
|||||||
package org.briarproject.briar.android.blog;
|
package org.briarproject.briar.android.blog;
|
||||||
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.text.Editable;
|
import android.text.Editable;
|
||||||
import android.text.TextWatcher;
|
import android.text.TextWatcher;
|
||||||
import android.view.LayoutInflater;
|
import android.view.LayoutInflater;
|
||||||
import android.view.Menu;
|
|
||||||
import android.view.MenuInflater;
|
|
||||||
import android.view.MenuItem;
|
|
||||||
import android.view.View;
|
import android.view.View;
|
||||||
import android.view.ViewGroup;
|
import android.view.ViewGroup;
|
||||||
import android.widget.Button;
|
import android.widget.Button;
|
||||||
@@ -17,27 +13,18 @@ import android.widget.ProgressBar;
|
|||||||
import org.briarproject.briar.R;
|
import org.briarproject.briar.R;
|
||||||
import org.briarproject.briar.android.activity.ActivityComponent;
|
import org.briarproject.briar.android.activity.ActivityComponent;
|
||||||
import org.briarproject.briar.android.fragment.BaseFragment;
|
import org.briarproject.briar.android.fragment.BaseFragment;
|
||||||
import org.briarproject.briar.android.fragment.ProgressFragment;
|
|
||||||
import org.briarproject.briar.android.util.ActivityLaunchers.GetContentAdvanced;
|
|
||||||
import org.briarproject.briar.android.util.ActivityLaunchers.OpenDocumentAdvanced;
|
|
||||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
||||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.activity.result.ActivityResultLauncher;
|
|
||||||
import androidx.annotation.RequiresApi;
|
|
||||||
import androidx.fragment.app.Fragment;
|
|
||||||
import androidx.lifecycle.ViewModelProvider;
|
import androidx.lifecycle.ViewModelProvider;
|
||||||
|
|
||||||
import static android.os.Build.VERSION.SDK_INT;
|
|
||||||
import static android.view.View.GONE;
|
import static android.view.View.GONE;
|
||||||
import static android.view.View.VISIBLE;
|
import static android.view.View.VISIBLE;
|
||||||
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
import static android.view.inputmethod.EditorInfo.IME_ACTION_DONE;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
|
import static org.briarproject.briar.android.util.UiUtils.hideSoftKeyboard;
|
||||||
import static org.briarproject.briar.android.util.UiUtils.launchActivityToOpenFile;
|
|
||||||
import static org.briarproject.briar.android.util.UiUtils.showFragment;
|
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
@MethodsNotNullByDefault
|
||||||
@ParametersNotNullByDefault
|
@ParametersNotNullByDefault
|
||||||
@@ -52,15 +39,6 @@ public class RssFeedImportFragment extends BaseFragment {
|
|||||||
private Button importButton;
|
private Button importButton;
|
||||||
private ProgressBar progressBar;
|
private ProgressBar progressBar;
|
||||||
|
|
||||||
@RequiresApi(19)
|
|
||||||
private final ActivityResultLauncher<String[]> docLauncher =
|
|
||||||
registerForActivityResult(new OpenDocumentAdvanced(),
|
|
||||||
this::onFileChosen);
|
|
||||||
|
|
||||||
private final ActivityResultLauncher<String> contentLauncher =
|
|
||||||
registerForActivityResult(new GetContentAdvanced(),
|
|
||||||
this::onFileChosen);
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void injectFragment(ActivityComponent component) {
|
public void injectFragment(ActivityComponent component) {
|
||||||
component.inject(this);
|
component.inject(this);
|
||||||
@@ -74,7 +52,6 @@ public class RssFeedImportFragment extends BaseFragment {
|
|||||||
@Nullable ViewGroup container,
|
@Nullable ViewGroup container,
|
||||||
@Nullable Bundle savedInstanceState) {
|
@Nullable Bundle savedInstanceState) {
|
||||||
requireActivity().setTitle(getString(R.string.blogs_rss_feeds_import));
|
requireActivity().setTitle(getString(R.string.blogs_rss_feeds_import));
|
||||||
if (SDK_INT >= 19) setHasOptionsMenu(true);
|
|
||||||
View v = inflater.inflate(R.layout.fragment_rss_feed_import,
|
View v = inflater.inflate(R.layout.fragment_rss_feed_import,
|
||||||
container, false);
|
container, false);
|
||||||
|
|
||||||
@@ -115,40 +92,11 @@ public class RssFeedImportFragment extends BaseFragment {
|
|||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
|
||||||
if (SDK_INT >= 19) {
|
|
||||||
inflater.inflate(R.menu.rss_feed_import_actions, menu);
|
|
||||||
}
|
|
||||||
super.onCreateOptionsMenu(menu, inflater);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onOptionsItemSelected(MenuItem item) {
|
|
||||||
if (item.getItemId() == R.id.action_import_file && SDK_INT >= 19) {
|
|
||||||
launchActivityToOpenFile(requireContext(), docLauncher,
|
|
||||||
contentLauncher, "*/*");
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return super.onOptionsItemSelected(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getUniqueTag() {
|
public String getUniqueTag() {
|
||||||
return TAG;
|
return TAG;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void onFileChosen(@Nullable Uri uri) {
|
|
||||||
if (uri == null) return;
|
|
||||||
// show progress fragment
|
|
||||||
Fragment f = ProgressFragment.newInstance(
|
|
||||||
getString(R.string.blogs_rss_feeds_import_progress));
|
|
||||||
String tag = ProgressFragment.TAG;
|
|
||||||
showFragment(getParentFragmentManager(), f, tag);
|
|
||||||
// view model will import and change state that activity will react to
|
|
||||||
viewModel.importFeed(uri);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void enableOrDisableImportButton() {
|
private void enableOrDisableImportButton() {
|
||||||
String url = urlInput.getText().toString();
|
String url = urlInput.getText().toString();
|
||||||
importButton.setEnabled(viewModel.validateAndNormaliseUrl(url) != null);
|
importButton.setEnabled(viewModel.validateAndNormaliseUrl(url) != null);
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package org.briarproject.briar.android.blog;
|
package org.briarproject.briar.android.blog;
|
||||||
|
|
||||||
import android.app.Application;
|
import android.app.Application;
|
||||||
import android.content.ContentResolver;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.util.Patterns;
|
import android.util.Patterns;
|
||||||
|
|
||||||
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
import org.briarproject.bramble.api.db.DatabaseExecutor;
|
||||||
@@ -13,10 +11,6 @@ import org.briarproject.bramble.api.lifecycle.IoExecutor;
|
|||||||
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
import org.briarproject.bramble.api.lifecycle.LifecycleManager;
|
||||||
import org.briarproject.bramble.api.sync.GroupId;
|
import org.briarproject.bramble.api.sync.GroupId;
|
||||||
import org.briarproject.bramble.api.system.AndroidExecutor;
|
import org.briarproject.bramble.api.system.AndroidExecutor;
|
||||||
import org.briarproject.briar.android.blog.RssImportResult.FileImportError;
|
|
||||||
import org.briarproject.briar.android.blog.RssImportResult.FileImportSuccess;
|
|
||||||
import org.briarproject.briar.android.blog.RssImportResult.UrlImportError;
|
|
||||||
import org.briarproject.briar.android.blog.RssImportResult.UrlImportSuccess;
|
|
||||||
import org.briarproject.briar.android.viewmodel.DbViewModel;
|
import org.briarproject.briar.android.viewmodel.DbViewModel;
|
||||||
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
import org.briarproject.briar.android.viewmodel.LiveEvent;
|
||||||
import org.briarproject.briar.android.viewmodel.LiveResult;
|
import org.briarproject.briar.android.viewmodel.LiveResult;
|
||||||
@@ -26,7 +20,6 @@ import org.briarproject.briar.api.feed.FeedManager;
|
|||||||
import org.briarproject.nullsafety.NotNullByDefault;
|
import org.briarproject.nullsafety.NotNullByDefault;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@@ -37,7 +30,6 @@ import java.util.logging.Logger;
|
|||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
import androidx.annotation.UiThread;
|
|
||||||
import androidx.lifecycle.LiveData;
|
import androidx.lifecycle.LiveData;
|
||||||
import androidx.lifecycle.MutableLiveData;
|
import androidx.lifecycle.MutableLiveData;
|
||||||
|
|
||||||
@@ -60,9 +52,11 @@ class RssFeedViewModel extends DbViewModel {
|
|||||||
private final MutableLiveData<LiveResult<List<Feed>>> feeds =
|
private final MutableLiveData<LiveResult<List<Feed>>> feeds =
|
||||||
new MutableLiveData<>();
|
new MutableLiveData<>();
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private volatile String urlFailedImport = null;
|
||||||
private final MutableLiveData<Boolean> isImporting =
|
private final MutableLiveData<Boolean> isImporting =
|
||||||
new MutableLiveData<>(false);
|
new MutableLiveData<>(false);
|
||||||
private final MutableLiveEvent<RssImportResult> importResult =
|
private final MutableLiveEvent<Boolean> importResult =
|
||||||
new MutableLiveEvent<>();
|
new MutableLiveEvent<>();
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
@@ -126,7 +120,7 @@ class RssFeedViewModel extends DbViewModel {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
LiveEvent<RssImportResult> getImportResult() {
|
LiveEvent<Boolean> getImportResult() {
|
||||||
return importResult;
|
return importResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -136,6 +130,7 @@ class RssFeedViewModel extends DbViewModel {
|
|||||||
|
|
||||||
void importFeed(String url) {
|
void importFeed(String url) {
|
||||||
isImporting.setValue(true);
|
isImporting.setValue(true);
|
||||||
|
urlFailedImport = null;
|
||||||
ioExecutor.execute(() -> {
|
ioExecutor.execute(() -> {
|
||||||
try {
|
try {
|
||||||
Feed feed = feedManager.addFeed(url);
|
Feed feed = feedManager.addFeed(url);
|
||||||
@@ -150,38 +145,19 @@ class RssFeedViewModel extends DbViewModel {
|
|||||||
updated = feedList;
|
updated = feedList;
|
||||||
}
|
}
|
||||||
feeds.postValue(new LiveResult<>(updated));
|
feeds.postValue(new LiveResult<>(updated));
|
||||||
importResult.postEvent(new UrlImportSuccess());
|
importResult.postEvent(true);
|
||||||
} catch (DbException | IOException e) {
|
} catch (DbException | IOException e) {
|
||||||
logException(LOG, WARNING, e);
|
logException(LOG, WARNING, e);
|
||||||
importResult.postEvent(new UrlImportError(url));
|
urlFailedImport = url;
|
||||||
|
importResult.postEvent(false);
|
||||||
} finally {
|
} finally {
|
||||||
isImporting.postValue(false);
|
isImporting.postValue(false);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@Nullable
|
||||||
void importFeed(Uri uri) {
|
String getUrlFailedImport() {
|
||||||
ContentResolver contentResolver = getApplication().getContentResolver();
|
return urlFailedImport;
|
||||||
ioExecutor.execute(() -> {
|
|
||||||
try (InputStream is = contentResolver.openInputStream(uri)) {
|
|
||||||
Feed feed = feedManager.addFeed(is);
|
|
||||||
// Update the feed if it was already present
|
|
||||||
List<Feed> feedList = getList(feeds);
|
|
||||||
if (feedList == null) feedList = new ArrayList<>();
|
|
||||||
List<Feed> updated = updateListItems(feedList,
|
|
||||||
f -> f.equals(feed), f -> feed);
|
|
||||||
// Add the feed if it wasn't already present
|
|
||||||
if (updated == null) {
|
|
||||||
feedList.add(feed);
|
|
||||||
updated = feedList;
|
|
||||||
}
|
|
||||||
feeds.postValue(new LiveResult<>(updated));
|
|
||||||
importResult.postEvent(new FileImportSuccess());
|
|
||||||
} catch (IOException | DbException e) {
|
|
||||||
logException(LOG, WARNING, e);
|
|
||||||
importResult.postEvent(new FileImportError());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
package org.briarproject.briar.android.blog;
|
|
||||||
|
|
||||||
import org.briarproject.nullsafety.NotNullByDefault;
|
|
||||||
|
|
||||||
@NotNullByDefault
|
|
||||||
abstract class RssImportResult {
|
|
||||||
|
|
||||||
static class UrlImportSuccess extends RssImportResult {
|
|
||||||
}
|
|
||||||
|
|
||||||
static class UrlImportError extends RssImportResult {
|
|
||||||
final String url;
|
|
||||||
|
|
||||||
UrlImportError(String url) {
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class FileImportSuccess extends RssImportResult {
|
|
||||||
}
|
|
||||||
|
|
||||||
static class FileImportError extends RssImportResult {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
package org.briarproject.briar.android.fragment;
|
|
||||||
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.view.LayoutInflater;
|
|
||||||
import android.view.View;
|
|
||||||
import android.view.ViewGroup;
|
|
||||||
import android.widget.TextView;
|
|
||||||
|
|
||||||
import org.briarproject.briar.R;
|
|
||||||
import org.briarproject.nullsafety.MethodsNotNullByDefault;
|
|
||||||
import org.briarproject.nullsafety.ParametersNotNullByDefault;
|
|
||||||
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
@MethodsNotNullByDefault
|
|
||||||
@ParametersNotNullByDefault
|
|
||||||
public class ProgressFragment extends BaseFragment {
|
|
||||||
|
|
||||||
public static final String TAG = ProgressFragment.class.getName();
|
|
||||||
|
|
||||||
private static final String PROGRESS_MSG = "progressMessage";
|
|
||||||
|
|
||||||
public static ProgressFragment newInstance(String message) {
|
|
||||||
ProgressFragment f = new ProgressFragment();
|
|
||||||
Bundle args = new Bundle();
|
|
||||||
args.putString(PROGRESS_MSG, message);
|
|
||||||
f.setArguments(args);
|
|
||||||
return f;
|
|
||||||
}
|
|
||||||
|
|
||||||
private String progressMessage;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getUniqueTag() {
|
|
||||||
return TAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCreate(@Nullable Bundle savedInstanceState) {
|
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
Bundle args = requireArguments();
|
|
||||||
progressMessage = args.getString(PROGRESS_MSG);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable
|
|
||||||
@Override
|
|
||||||
public View onCreateView(LayoutInflater inflater,
|
|
||||||
@Nullable ViewGroup container,
|
|
||||||
@Nullable Bundle savedInstanceState) {
|
|
||||||
View v = inflater
|
|
||||||
.inflate(R.layout.fragment_progress, container, false);
|
|
||||||
TextView msg = v.findViewById(R.id.progressMessage);
|
|
||||||
msg.setText(progressMessage);
|
|
||||||
return v;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -145,7 +145,19 @@ public class MailboxStatusFragment extends Fragment {
|
|||||||
@DrawableRes int iconRes;
|
@DrawableRes int iconRes;
|
||||||
String title;
|
String title;
|
||||||
String message = null;
|
String message = null;
|
||||||
if (status.getMailboxCompatibility() < 0) {
|
if (status.hasProblem(System.currentTimeMillis())) {
|
||||||
|
tintRes = R.color.briar_red_500;
|
||||||
|
title = getString(R.string.mailbox_status_failure_title);
|
||||||
|
iconRes = R.drawable.alerts_and_states_error;
|
||||||
|
showUnlinkWarning = false;
|
||||||
|
wizardButton.setVisibility(VISIBLE);
|
||||||
|
} else if (status.getAttemptsSinceSuccess() > 0) {
|
||||||
|
iconRes = R.drawable.ic_help_outline_white;
|
||||||
|
title = getString(R.string.mailbox_status_problem_title);
|
||||||
|
tintRes = R.color.briar_orange_500;
|
||||||
|
showUnlinkWarning = false;
|
||||||
|
wizardButton.setVisibility(VISIBLE);
|
||||||
|
} else if (status.getMailboxCompatibility() < 0) {
|
||||||
tintRes = R.color.briar_red_500;
|
tintRes = R.color.briar_red_500;
|
||||||
if (status.getMailboxCompatibility() == API_CLIENT_TOO_OLD) {
|
if (status.getMailboxCompatibility() == API_CLIENT_TOO_OLD) {
|
||||||
title = getString(R.string.mailbox_status_app_too_old_title);
|
title = getString(R.string.mailbox_status_app_too_old_title);
|
||||||
@@ -160,18 +172,6 @@ public class MailboxStatusFragment extends Fragment {
|
|||||||
iconRes = R.drawable.alerts_and_states_error;
|
iconRes = R.drawable.alerts_and_states_error;
|
||||||
showUnlinkWarning = true;
|
showUnlinkWarning = true;
|
||||||
wizardButton.setVisibility(GONE);
|
wizardButton.setVisibility(GONE);
|
||||||
} else if (status.hasProblem(System.currentTimeMillis())) {
|
|
||||||
tintRes = R.color.briar_red_500;
|
|
||||||
title = getString(R.string.mailbox_status_failure_title);
|
|
||||||
iconRes = R.drawable.alerts_and_states_error;
|
|
||||||
showUnlinkWarning = false;
|
|
||||||
wizardButton.setVisibility(VISIBLE);
|
|
||||||
} else if (status.getAttemptsSinceSuccess() > 0) {
|
|
||||||
iconRes = R.drawable.ic_help_outline_white;
|
|
||||||
title = getString(R.string.mailbox_status_problem_title);
|
|
||||||
tintRes = R.color.briar_orange_500;
|
|
||||||
showUnlinkWarning = false;
|
|
||||||
wizardButton.setVisibility(VISIBLE);
|
|
||||||
} else {
|
} else {
|
||||||
iconRes = R.drawable.ic_check_circle_outline;
|
iconRes = R.drawable.ic_check_circle_outline;
|
||||||
title = getString(R.string.mailbox_status_connected_title);
|
title = getString(R.string.mailbox_status_connected_title);
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<androidx.core.widget.NestedScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="match_parent"
|
|
||||||
android:fillViewport="true">
|
|
||||||
|
|
||||||
<androidx.constraintlayout.widget.ConstraintLayout
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_margin="@dimen/margin_xlarge">
|
|
||||||
|
|
||||||
<ProgressBar
|
|
||||||
android:id="@+id/progress"
|
|
||||||
style="?android:attr/progressBarStyleLarge"
|
|
||||||
android:layout_width="@dimen/hero_square"
|
|
||||||
android:layout_height="@dimen/hero_square"
|
|
||||||
android:indeterminate="true"
|
|
||||||
app:layout_constraintBottom_toTopOf="@+id/progressMessage"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
|
||||||
app:layout_constraintVertical_bias="0.25"
|
|
||||||
app:layout_constraintVertical_chainStyle="packed"
|
|
||||||
tools:ignore="ContentDescription" />
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/progressMessage"
|
|
||||||
android:layout_width="0dp"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_marginTop="@dimen/margin_xlarge"
|
|
||||||
android:gravity="center"
|
|
||||||
android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
|
|
||||||
app:layout_constraintBottom_toBottomOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintTop_toBottomOf="@+id/progress"
|
|
||||||
tools:text="@string/blogs_rss_feeds_import_progress" />
|
|
||||||
|
|
||||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
||||||
|
|
||||||
</androidx.core.widget.NestedScrollView>
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<menu
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto">
|
|
||||||
|
|
||||||
<item
|
|
||||||
android:id="@+id/action_import_file"
|
|
||||||
android:icon="@drawable/ic_add_white"
|
|
||||||
android:title="@string/blogs_rss_feeds_import_title"
|
|
||||||
app:showAsAction="never"/>
|
|
||||||
|
|
||||||
</menu>
|
|
||||||
@@ -104,7 +104,7 @@
|
|||||||
<string name="bt_plugin_status_disabled">Briar е настроен да не използва Bluetooth</string>
|
<string name="bt_plugin_status_disabled">Briar е настроен да не използва Bluetooth</string>
|
||||||
<!--Notifications-->
|
<!--Notifications-->
|
||||||
<string name="reminder_notification_title">Отписани сте от Briar</string>
|
<string name="reminder_notification_title">Отписани сте от Briar</string>
|
||||||
<string name="reminder_notification_text">За да влезете, докоснете</string>
|
<string name="reminder_notification_text">Докоснете за повторно влизане.</string>
|
||||||
<string name="reminder_notification_channel_title">Напомняне за вход в Briar</string>
|
<string name="reminder_notification_channel_title">Напомняне за вход в Briar</string>
|
||||||
<string name="reminder_notification_dismiss">Отказ</string>
|
<string name="reminder_notification_dismiss">Отказ</string>
|
||||||
<string name="ongoing_notification_title">Вписани в Briar</string>
|
<string name="ongoing_notification_title">Вписани в Briar</string>
|
||||||
@@ -235,8 +235,6 @@
|
|||||||
<string name="qr_code_invalid">Кодът за QR е недействителен</string>
|
<string name="qr_code_invalid">Кодът за QR е недействителен</string>
|
||||||
<string name="qr_code_too_old_1">Сканираният код за QR е от по-ранно издание на Briar.\n\nНека вашия контакт инсталира последното издание и да пробва отново.</string>
|
<string name="qr_code_too_old_1">Сканираният код за QR е от по-ранно издание на Briar.\n\nНека вашия контакт инсталира последното издание и да пробва отново.</string>
|
||||||
<string name="qr_code_too_new_1">Сканираният код за QR е от по-ново издание на Briar.\n\nИнсталирайте последното издание и пробвайте отново.</string>
|
<string name="qr_code_too_new_1">Сканираният код за QR е от по-ново издание на Briar.\n\nИнсталирайте последното издание и пробвайте отново.</string>
|
||||||
<string name="mailbox_qr_code_for_contact">Сканираният код за QR е от Briar Пощенска кутия.\n\nАко искате да свържете Пощенска кутия използвайте Настройки > Пощенска кутия от менюто.</string>
|
|
||||||
<string name="qr_code_format_unknown">Сканираният код за QR не предназначен за добавяне на контакт в Briar.\n\nЗа тази цел използвайте кода, на екрана на контакта ви.</string>
|
|
||||||
<string name="camera_error">Грешка в камерата</string>
|
<string name="camera_error">Грешка в камерата</string>
|
||||||
<string name="connecting_to_device">Свързване с устройство\u2026</string>
|
<string name="connecting_to_device">Свързване с устройство\u2026</string>
|
||||||
<string name="authenticating_with_device">Удостоверяване с устройство\u2026</string>
|
<string name="authenticating_with_device">Удостоверяване с устройство\u2026</string>
|
||||||
@@ -482,6 +480,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">Внасяне</string>
|
<string name="blogs_rss_feeds_import_button">Внасяне</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Aдрес на емисия</string>
|
<string name="blogs_rss_feeds_import_hint">Aдрес на емисия</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Грешка при внасяне на емисията.</string>
|
<string name="blogs_rss_feeds_import_error">Грешка при внасяне на емисията.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Емисията вече е внесена.</string>
|
||||||
<string name="blogs_rss_feeds">Емисии на RSS</string>
|
<string name="blogs_rss_feeds">Емисии на RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Внесена:</string>
|
<string name="blogs_rss_feeds_manage_imported">Внесена:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Автор:</string>
|
<string name="blogs_rss_feeds_manage_author">Автор:</string>
|
||||||
@@ -592,9 +591,7 @@
|
|||||||
<string name="mailbox_setup_download_link">Споделяне на препратка за изтегляне</string>
|
<string name="mailbox_setup_download_link">Споделяне на препратка за изтегляне</string>
|
||||||
<string name="mailbox_setup_button_scan">Сканиране на кода за QR на пощенска кутия</string>
|
<string name="mailbox_setup_button_scan">Сканиране на кода за QR на пощенска кутия</string>
|
||||||
<string name="permission_camera_qr_denied_body">Отказахте достъп до камерата, но достъп е необходим за сканиране на кодове за QR.\n\nОбмислете дали да не дадете разрешение.</string>
|
<string name="permission_camera_qr_denied_body">Отказахте достъп до камерата, но достъп е необходим за сканиране на кодове за QR.\n\nОбмислете дали да не дадете разрешение.</string>
|
||||||
<string name="mailbox_setup_connecting">Свързване с Пощенска кутия…</string>
|
|
||||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||||
<string name="mailbox_setup_connecting_info">Може да отнеме %1s</string>
|
|
||||||
<string name="mailbox_setup_already_paired_title">Пощенската кутия е вече свързана</string>
|
<string name="mailbox_setup_already_paired_title">Пощенската кутия е вече свързана</string>
|
||||||
<string name="mailbox_setup_already_paired_description">Прекъснете връзката с пощенската кутия от другото устройство и опитайте отново.</string>
|
<string name="mailbox_setup_already_paired_description">Прекъснете връзката с пощенската кутия от другото устройство и опитайте отново.</string>
|
||||||
<string name="mailbox_setup_io_error_title">Грешка при свързване</string>
|
<string name="mailbox_setup_io_error_title">Грешка при свързване</string>
|
||||||
|
|||||||
@@ -489,6 +489,7 @@ Així que l\'actualitzi li veureu una icona diferent .</string>
|
|||||||
<string name="blogs_rss_feeds_import_button">Subscriu-me</string>
|
<string name="blogs_rss_feeds_import_button">Subscriu-me</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Escriviu l\'URL del canal de notícies RSS</string>
|
<string name="blogs_rss_feeds_import_hint">Escriviu l\'URL del canal de notícies RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Ens sap greu! S\'ha produït un error en subscriure-us al vostre canal de notícies.</string>
|
<string name="blogs_rss_feeds_import_error">Ens sap greu! S\'ha produït un error en subscriure-us al vostre canal de notícies.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Aquest canal ja s\'ha importat.</string>
|
||||||
<string name="blogs_rss_feeds">Canals RSS</string>
|
<string name="blogs_rss_feeds">Canals RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importat:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importat:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
||||||
|
|||||||
@@ -60,8 +60,8 @@
|
|||||||
<string name="old_android_expiry_date_reached">Briar wird auf Android 4 nicht mehr unterstützt.\nBitte installiere Briar auf einem neueren Gerät.</string>
|
<string name="old_android_expiry_date_reached">Briar wird auf Android 4 nicht mehr unterstützt.\nBitte installiere Briar auf einem neueren Gerät.</string>
|
||||||
<string name="old_android_delete_account">Du kannst auf die Schaltfläche unten tippen, um dein Konto von diesem Gerät zu löschen.</string>
|
<string name="old_android_delete_account">Du kannst auf die Schaltfläche unten tippen, um dein Konto von diesem Gerät zu löschen.</string>
|
||||||
<string name="delete_account_button">Konto löschen</string>
|
<string name="delete_account_button">Konto löschen</string>
|
||||||
<string name="startup_open_database">Datenbank wird entschlüsselt…</string>
|
<string name="startup_open_database">Datenbank wird entschlüsselt...</string>
|
||||||
<string name="startup_migrate_database">Datenbank wird aktualisiert…</string>
|
<string name="startup_migrate_database">Datenbank wird aktualisiert...</string>
|
||||||
<string name="startup_compact_database">Datenbank wird komprimiert…</string>
|
<string name="startup_compact_database">Datenbank wird komprimiert…</string>
|
||||||
<!--Navigation Drawer-->
|
<!--Navigation Drawer-->
|
||||||
<string name="nav_drawer_open_description">Navigationsleiste öffnen</string>
|
<string name="nav_drawer_open_description">Navigationsleiste öffnen</string>
|
||||||
@@ -266,9 +266,9 @@
|
|||||||
<string name="pending_contact_requests_snackbar">Es gibt ausstehende Kontaktanfragen</string>
|
<string name="pending_contact_requests_snackbar">Es gibt ausstehende Kontaktanfragen</string>
|
||||||
<string name="pending_contact_requests">Ausstehende Kontaktanfragen</string>
|
<string name="pending_contact_requests">Ausstehende Kontaktanfragen</string>
|
||||||
<string name="no_pending_contacts">Keine ausstehenden Kontakte</string>
|
<string name="no_pending_contacts">Keine ausstehenden Kontakte</string>
|
||||||
<string name="waiting_for_contact_to_come_online">Warte auf Online-Aktivität des Kontakts…</string>
|
<string name="waiting_for_contact_to_come_online">Warte auf Online-Aktivität des Kontakts ...</string>
|
||||||
<string name="connecting">Verbinde…</string>
|
<string name="connecting">Verbinde…</string>
|
||||||
<string name="adding_contact">Kontakt hinzufügen…</string>
|
<string name="adding_contact">Kontakt hinzufügen...</string>
|
||||||
<string name="adding_contact_failed">Hinzufügen von Kontakt ist fehlgeschlagen</string>
|
<string name="adding_contact_failed">Hinzufügen von Kontakt ist fehlgeschlagen</string>
|
||||||
<string name="dialog_title_remove_pending_contact">Entfernung bestätigen</string>
|
<string name="dialog_title_remove_pending_contact">Entfernung bestätigen</string>
|
||||||
<string name="dialog_message_remove_pending_contact">Dieser Kontakt befindet sich noch beim Hinzufügen. Wenn er jetzt entfernt wird, wird das Hinzufügen abgebrochen.</string>
|
<string name="dialog_message_remove_pending_contact">Dieser Kontakt befindet sich noch beim Hinzufügen. Wenn er jetzt entfernt wird, wird das Hinzufügen abgebrochen.</string>
|
||||||
@@ -487,9 +487,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">RSS-Feed importieren</string>
|
<string name="blogs_rss_feeds_import">RSS-Feed importieren</string>
|
||||||
<string name="blogs_rss_feeds_import_button">Importieren</string>
|
<string name="blogs_rss_feeds_import_button">Importieren</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">URL des RSS-Feeds eingeben</string>
|
<string name="blogs_rss_feeds_import_hint">URL des RSS-Feeds eingeben</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">RSS-Feed wird importiert…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">Es tut uns Leid! Es gab einen Fehler beim Importieren deines Feeds.</string>
|
<string name="blogs_rss_feeds_import_error">Es tut uns Leid! Es gab einen Fehler beim Importieren deines Feeds.</string>
|
||||||
<string name="blogs_rss_feeds_import_title">Feed aus Datei importieren</string>
|
<string name="blogs_rss_feeds_import_exists">Dieser Feed ist bereits importiert.</string>
|
||||||
<string name="blogs_rss_feeds">RSS-Feeds</string>
|
<string name="blogs_rss_feeds">RSS-Feeds</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importiert:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importiert:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
||||||
@@ -730,7 +729,7 @@
|
|||||||
<string name="dev_report_saved">Der Bericht wurde gespeichert. Er wird verschickt, wenn du dich das nächste Mal bei Briar anmeldest.</string>
|
<string name="dev_report_saved">Der Bericht wurde gespeichert. Er wird verschickt, wenn du dich das nächste Mal bei Briar anmeldest.</string>
|
||||||
<string name="dev_report_error">Fehler: Senden des Reports fehlgeschlagen</string>
|
<string name="dev_report_error">Fehler: Senden des Reports fehlgeschlagen</string>
|
||||||
<!--Sign Out-->
|
<!--Sign Out-->
|
||||||
<string name="progress_title_logout">Von Briar abmelden…</string>
|
<string name="progress_title_logout">Von Briar abmelden...</string>
|
||||||
<!--Screen Filters & Tapjacking-->
|
<!--Screen Filters & Tapjacking-->
|
||||||
<string name="screen_filter_title">Bildschirmüberlagerung erkannt</string>
|
<string name="screen_filter_title">Bildschirmüberlagerung erkannt</string>
|
||||||
<string name="screen_filter_body">Eine andere App überlagert Briar. Um deine Sicherheit zu gewährleisten, reagiert Briar in diesem Fall nicht auf deine Eingaben.\n\nDie folgenden Apps könnten überlagern:\n\n%1$s</string>
|
<string name="screen_filter_body">Eine andere App überlagert Briar. Um deine Sicherheit zu gewährleisten, reagiert Briar in diesem Fall nicht auf deine Eingaben.\n\nDie folgenden Apps könnten überlagern:\n\n%1$s</string>
|
||||||
|
|||||||
@@ -443,7 +443,6 @@
|
|||||||
<string name="forum_declined_toast">La invitación ha sido rechazada</string>
|
<string name="forum_declined_toast">La invitación ha sido rechazada</string>
|
||||||
<string name="shared_by_format">Compartido por %s</string>
|
<string name="shared_by_format">Compartido por %s</string>
|
||||||
<string name="forum_invitation_already_sharing">Ya se está compartiendo</string>
|
<string name="forum_invitation_already_sharing">Ya se está compartiendo</string>
|
||||||
<string name="forum_invitation_already_invited">Invitación ya enviada</string>
|
|
||||||
<string name="forum_invitation_response_accepted_sent">Aceptaste la invitación al foro de %s.</string>
|
<string name="forum_invitation_response_accepted_sent">Aceptaste la invitación al foro de %s.</string>
|
||||||
<string name="forum_invitation_response_declined_sent">Rechazaste la invitación al foro de %s.</string>
|
<string name="forum_invitation_response_declined_sent">Rechazaste la invitación al foro de %s.</string>
|
||||||
<string name="forum_invitation_response_declined_auto">La invitación al foro de %s fue automáticamente rechazada.</string>
|
<string name="forum_invitation_response_declined_auto">La invitación al foro de %s fue automáticamente rechazada.</string>
|
||||||
@@ -496,6 +495,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">Importar</string>
|
<string name="blogs_rss_feeds_import_button">Importar</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Introduce la URL del canal RSS</string>
|
<string name="blogs_rss_feeds_import_hint">Introduce la URL del canal RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_error">¡Lo sentimos! Hubo un error importando tu canal.</string>
|
<string name="blogs_rss_feeds_import_error">¡Lo sentimos! Hubo un error importando tu canal.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Ese canal ya está importado.</string>
|
||||||
<string name="blogs_rss_feeds">Canales RSS</string>
|
<string name="blogs_rss_feeds">Canales RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importado:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importado:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
||||||
|
|||||||
@@ -510,6 +510,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">وارد کردن</string>
|
<string name="blogs_rss_feeds_import_button">وارد کردن</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">آدرس خوراک RSS را وارد کنید</string>
|
<string name="blogs_rss_feeds_import_hint">آدرس خوراک RSS را وارد کنید</string>
|
||||||
<string name="blogs_rss_feeds_import_error">متاسفیم! وارد کردن خوراک شما با خطا مواجه شده است.</string>
|
<string name="blogs_rss_feeds_import_error">متاسفیم! وارد کردن خوراک شما با خطا مواجه شده است.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">این خوراک وارد شده است.</string>
|
||||||
<string name="blogs_rss_feeds">خوراک های RSS</string>
|
<string name="blogs_rss_feeds">خوراک های RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">وارد شده:</string>
|
<string name="blogs_rss_feeds_manage_imported">وارد شده:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">نویسنده:</string>
|
<string name="blogs_rss_feeds_manage_author">نویسنده:</string>
|
||||||
|
|||||||
@@ -482,6 +482,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">Importer</string>
|
<string name="blogs_rss_feeds_import_button">Importer</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Saisir l’URL du fil RSS</string>
|
<string name="blogs_rss_feeds_import_hint">Saisir l’URL du fil RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Nous sommes désolés ! Une erreur est survenue lors de l’importation de votre fil.</string>
|
<string name="blogs_rss_feeds_import_error">Nous sommes désolés ! Une erreur est survenue lors de l’importation de votre fil.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Ce fil est déjà importé.</string>
|
||||||
<string name="blogs_rss_feeds">Fils RSS</string>
|
<string name="blogs_rss_feeds">Fils RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importés :</string>
|
<string name="blogs_rss_feeds_manage_imported">Importés :</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Auteur :</string>
|
<string name="blogs_rss_feeds_manage_author">Auteur :</string>
|
||||||
|
|||||||
@@ -466,6 +466,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">Flytja inn</string>
|
<string name="blogs_rss_feeds_import_button">Flytja inn</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Settu inn slóðina á RSS-streymið</string>
|
<string name="blogs_rss_feeds_import_hint">Settu inn slóðina á RSS-streymið</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Því miður! Það kom upp villa við að flytja inn streymið.</string>
|
<string name="blogs_rss_feeds_import_error">Því miður! Það kom upp villa við að flytja inn streymið.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Þegar er búið að flytja inn þetta streymi.</string>
|
||||||
<string name="blogs_rss_feeds">RSS-fréttastreymi</string>
|
<string name="blogs_rss_feeds">RSS-fréttastreymi</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Flutt inn:</string>
|
<string name="blogs_rss_feeds_manage_imported">Flutt inn:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Höfundur:</string>
|
<string name="blogs_rss_feeds_manage_author">Höfundur:</string>
|
||||||
|
|||||||
@@ -501,9 +501,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">Importa RSS Feed</string>
|
<string name="blogs_rss_feeds_import">Importa RSS Feed</string>
|
||||||
<string name="blogs_rss_feeds_import_button">Importa</string>
|
<string name="blogs_rss_feeds_import_button">Importa</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Inserire l\'URL dell\'RSS feed</string>
|
<string name="blogs_rss_feeds_import_hint">Inserire l\'URL dell\'RSS feed</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">Importazione RSS Feed…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">Ci dispiace! C\'è stato un errore nell\'importazione del tuo feed.</string>
|
<string name="blogs_rss_feeds_import_error">Ci dispiace! C\'è stato un errore nell\'importazione del tuo feed.</string>
|
||||||
<string name="blogs_rss_feeds_import_title">Importa feed da file</string>
|
<string name="blogs_rss_feeds_import_exists">Quel flusso è già importato.</string>
|
||||||
<string name="blogs_rss_feeds">Flussi RSS</string>
|
<string name="blogs_rss_feeds">Flussi RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importato:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importato:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autore:</string>
|
<string name="blogs_rss_feeds_manage_author">Autore:</string>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<?xml version='1.0' encoding='UTF-8'?>
|
<?xml version='1.0' encoding='UTF-8'?>
|
||||||
<resources xmlns:tools="http://schemas.android.com/tools">
|
<resources xmlns:tools="http://schemas.android.com/tools">
|
||||||
<!--Setup-->
|
<!--Setup-->
|
||||||
<string name="setup_title">Briarへようこそ</string>
|
<string name="setup_title">Briar へようこそ</string>
|
||||||
<string name="setup_name_explanation">あなたのニックネームは、常に、あなたが投稿するコンテンツとともに表示されます。プロフィール作成後、編集はできません。</string>
|
<string name="setup_name_explanation">あなたのニックネームは、常に、あなたが投稿するコンテンツとともに表示されます。プロフィール作成後、編集はできません。</string>
|
||||||
<string name="setup_next">次へ</string>
|
<string name="setup_next">次へ</string>
|
||||||
<string name="setup_password_intro">パスワードを選択</string>
|
<string name="setup_password_intro">パスワードを選択</string>
|
||||||
<string name="setup_password_explanation">Briarのアカウント情報はクラウドではなく、暗号化された端末に保存されます。アプリのアンインストールやパスワードを紛失した場合、アカウントへのアクセスとデータを回復する手段はありません。\n\n推測するのが難しい、長いパスワードを設定してください。ランダムな4単語やランダムな10文字と数字と記号を組み合わせたものなどです。</string>
|
<string name="setup_password_explanation">Briar のアカウント情報はクラウドではなく、暗号化された端末に保存されます。アプリのアンインストールやパスワードを紛失した場合、アカウントへのアクセスとデータを回復する手段はありません。\n\n推測するのが難しい、長いパスワードを設定してください。ランダムな4単語やランダムな10文字と数字と記号を組み合わせたものなどです。</string>
|
||||||
<string name="dnkm_doze_intro">メッセージを受信するために、Briarはバックグラウンドで接続を維持する必要があります。</string>
|
<string name="dnkm_doze_intro">メッセージを受信するために、Briar はバックグラウンドで接続を維持する必要があります。</string>
|
||||||
<string name="dnkm_doze_explanation">メッセージを受信するために、Briarはバックグラウンドで接続を維持する必要があります。 Briarが接続を維持できるように、バッテリーの最適化を無効にしてください。</string>
|
<string name="dnkm_doze_explanation">メッセージを受信するために、Briar はバックグラウンドで接続を維持する必要があります。 Briar が接続を維持できるように、バッテリーの最適化を無効にしてください。</string>
|
||||||
<string name="choose_nickname">ニックネームを入力</string>
|
<string name="choose_nickname">ニックネームを入力</string>
|
||||||
<string name="choose_password">パスワードを入力</string>
|
<string name="choose_password">パスワードを入力</string>
|
||||||
<string name="confirm_password">確認のため再度パスワードを入力</string>
|
<string name="confirm_password">確認のため再度パスワードを入力</string>
|
||||||
@@ -17,42 +17,42 @@
|
|||||||
<string name="create_account_button">アカウントを作成</string>
|
<string name="create_account_button">アカウントを作成</string>
|
||||||
<string name="more_info">詳細情報</string>
|
<string name="more_info">詳細情報</string>
|
||||||
<string name="don_t_ask_again">次からは尋ねない</string>
|
<string name="don_t_ask_again">次からは尋ねない</string>
|
||||||
<string name="dnkm_huawei_protected_text">下のボタンをタップして、「保護されたアプリ」画面で Briarが保護されていることを確認してください。</string>
|
<string name="dnkm_huawei_protected_text">下のボタンをタップして、「保護されたアプリ」画面で Briar が保護されていることを確認してください。</string>
|
||||||
<string name="dnkm_huawei_protected_button">Briarを保護する</string>
|
<string name="dnkm_huawei_protected_button">Briar を保護する</string>
|
||||||
<string name="dnkm_huawei_protected_help">Briarが保護されたアプリのリストに追加されていないと、Briarはバックグラウンドで実行することができません。</string>
|
<string name="dnkm_huawei_protected_help">Briar が保護されたアプリのリストに追加されていないと、Briar はバックグラウンドで実行することができません。</string>
|
||||||
<string name="dnkm_huawei_app_launch_text">下のボタンをタップして「アプリの起動」画面を開き、Briarが「手動で管理する」に設定されていることを確認してください。</string>
|
<string name="dnkm_huawei_app_launch_text">下のボタンをタップして「アプリの起動」画面を開き、Briar が「手動で管理する」に設定されていることを確認してください。</string>
|
||||||
<string name="dnkm_huawei_app_launch_help">「アプリ起動」画面で Briarを「手動で管理する」に設定していないと、バックグラウンドで動作させることができません。</string>
|
<string name="dnkm_huawei_app_launch_help">「アプリ起動」画面で Briar を「手動で管理する」に設定していないと、バックグラウンドで動作させることができません。</string>
|
||||||
<string name="dnkm_xiaomi_text">バックグラウンドで実行するには、Briarを最近のアプリのリストにロックする必要があります。</string>
|
<string name="dnkm_xiaomi_text">バックグラウンドで実行するには、Briar を最近のアプリのリストにロックする必要があります。</string>
|
||||||
<string name="dnkm_xiaomi_button">Briarを保護する</string>
|
<string name="dnkm_xiaomi_button">Briar を保護する</string>
|
||||||
<string name="dnkm_xiaomi_help">Briarが最近のアプリのリストにロックされていないと、バックグラウンドで実行することができません。</string>
|
<string name="dnkm_xiaomi_help">Briar が最近のアプリのリストにロックされていないと、バックグラウンドで実行することができません。</string>
|
||||||
<string name="dnkm_xiaomi_dialog_body_old">1. 最近使ったアプリのリスト(アプリスイッチャーともいう)を開いて下さい。\n\n2. Briarの画像を下にスワイプすると、南京錠のアイコンが表示されます。\n\n3. ロックされていない場合は、タップしてロックします。</string>
|
<string name="dnkm_xiaomi_dialog_body_old">1. 最近使ったアプリのリスト(アプリスイッチャーともいう)を開いて下さい。\n\n2. Briar の画像を下にスワイプすると、南京錠のアイコンが表示されます。\n\n3. ロックされていない場合は、タップしてロックします。</string>
|
||||||
<string name="dnkm_warning_dozed_1">Briarはバックグラウンドで実行できませんでした</string>
|
<string name="dnkm_warning_dozed_1">Briarはバックグラウンドで実行することができませんでした</string>
|
||||||
<!--Login-->
|
<!--Login-->
|
||||||
<string name="enter_password">パスワード</string>
|
<string name="enter_password">パスワード</string>
|
||||||
<string name="try_again">パスワードが間違っています。もう一度入力してください。</string>
|
<string name="try_again">パスワードが間違っています。もう一度入力してください。</string>
|
||||||
<string name="dialog_title_cannot_check_password">パスワードを確認できません</string>
|
<string name="dialog_title_cannot_check_password">パスワードを確認できません</string>
|
||||||
<string name="dialog_message_cannot_check_password">Briarがパスワードを確認することができませんでした。この問題を解決するには、端末の再起動を試してください。</string>
|
<string name="dialog_message_cannot_check_password">Briar がパスワードを確認することができませんでした。この問題を解決するには、端末の再起動を試してください。</string>
|
||||||
<string name="sign_in_button">サインイン</string>
|
<string name="sign_in_button">サインイン</string>
|
||||||
<string name="forgotten_password">パスワードを忘れました</string>
|
<string name="forgotten_password">パスワードを忘れました</string>
|
||||||
<string name="dialog_title_lost_password">パスワードを紛失</string>
|
<string name="dialog_title_lost_password">パスワードを紛失</string>
|
||||||
<string name="dialog_message_lost_password">Briarアカウントはクラウド上ではなく、暗号化さた上であなたの端末に保存さています。したがって、Briarはパスワードをリセットできません。アカウントを削除して、はじめからやり直しますか?\n\n注意:あなたのID、連絡先、メッセージは永久に失われます。</string>
|
<string name="dialog_message_lost_password">Briar アカウントはクラウド上ではなく、暗号化さた上であなたの端末に保存さています。したがって、Briar はパスワードをリセットできません。アカウントを削除して、はじめからやり直しますか?\n\n注意:あなたのID、連絡先、メッセージは永久に失われます。</string>
|
||||||
<string name="startup_failed_activity_title">Briarの起動に失敗</string>
|
<string name="startup_failed_activity_title">Briar の起動に失敗しました</string>
|
||||||
<string name="startup_failed_clock_error">お使いの端末の時計が正しくないため、Briarは起動できませんでした。\n\n端末の時計を正しい時刻に設定してから、もう一度試してください。</string>
|
<string name="startup_failed_clock_error">お使いの端末の時計が正しくないため、Briar は起動できませんでした。\n\n端末の時計を正しい時刻に設定してから、もう一度試してください。</string>
|
||||||
<string name="startup_failed_db_error">Briarは、あなたのアカウント、連絡先、メッセージを含むデータベースを開くことができませんでした。\n\nアプリを最新版にアップグレードしてもう一度お試しいただくか、パスワード入力画面で「パスワードを忘れました」を選択して新しいアカウントを設定してください。</string>
|
<string name="startup_failed_db_error">Briar は、あなたのアカウント、連絡先、メッセージを含むデータベースを開くことができませんでした。\n\nアプリを最新版にアップグレードしてもう一度お試しいただくか、パスワード入力画面で「パスワードを忘れました」を選択して新しいアカウントを設定してください。</string>
|
||||||
<string name="startup_failed_data_too_old_error">あなたのアカウントは古いバージョンのアプリで作成されたもので、このバージョンでは開くことができません。\n\n古いバージョンを再インストールするか、パスワード入力画面で\'パスワードを忘れました\'を選択して新しいアカウントを設定する必要があります。</string>
|
<string name="startup_failed_data_too_old_error">あなたのアカウントは古いバージョンのアプリで作成されたもので、このバージョンでは開くことができません。\n\n古いバージョンを再インストールするか、パスワード入力画面で\'パスワードを忘れました\'を選択して新しいアカウントを設定する必要があります。</string>
|
||||||
<string name="startup_failed_data_too_new_error">あなたのアカウントは、このアプリの新しいバージョンで作成されたもので、このバージョンでは開くことができません。\n\n最新版にアップグレードしてから、もう一度試してください。</string>
|
<string name="startup_failed_data_too_new_error">あなたのアカウントは、このアプリの新しいバージョンで作成されたもので、このバージョンでは開くことができません。\n\n最新版にアップグレードしてから、もう一度試してください。</string>
|
||||||
<string name="startup_failed_service_error">Briarは要求されたコンポーネントを起動できませんでした。\n\nアプリの最新版にアップグレードしてから、もう一度試してください。</string>
|
<string name="startup_failed_service_error">Briar は、必要なコンポーネントを起動できませんでした。\n\nアプリの最新版にアップグレードしてから、もう一度試してください。</string>
|
||||||
<plurals name="expiry_warning">
|
<plurals name="expiry_warning">
|
||||||
<item quantity="other">これは、Briarのテストバージョンです。 アカウントはあと%d日で期限切れになり、更新できません。</item>
|
<item quantity="other">これは、Briar のテストバージョンです。 アカウントはあと%d日で期限切れになり、更新できません。</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<plurals name="old_android_expiry_warning">
|
<plurals name="old_android_expiry_warning">
|
||||||
<item quantity="other">Android 4はサポートされなくなりました。Briarは(%d日後に)%s上での動作を停止します。新しい端末に Briarをインストールして、新しいアカウントを作成してください。</item>
|
<item quantity="other">Android 4はサポートされなくなりました。Briar は(%d日後に)%s上での動作を停止します。新しい端末に Briar をインストールして、新しいアカウントを作成してください。</item>
|
||||||
</plurals>
|
</plurals>
|
||||||
<string name="expiry_date_reached">このソフトウェアの有効期限が切れました。テストに参加してくださりありがとうございます!</string>
|
<string name="expiry_date_reached">このソフトウェアの有効期限が切れました。テストに参加してくださりありがとうございます!</string>
|
||||||
<string name="download_briar">Briarの使用を続けるには、最新のリリースをダウンロードしてください。</string>
|
<string name="download_briar">Briarの使用を続けるには、最新リリースをダウンロードしてください。</string>
|
||||||
<string name="create_new_account">新しいアカウントを作成する必要があります。同じニックネームも使用できます。</string>
|
<string name="create_new_account">新しいアカウントを作成する必要があります。同じニックネームも使用できます。</string>
|
||||||
<string name="download_briar_button">最新リリースをダウンロード</string>
|
<string name="download_briar_button">最新リリースをダウンロード</string>
|
||||||
<string name="old_android_expiry_date_reached">BriarはAndroid 4では動作しなくなりました。\n新しい端末にBriarをインストールしてください。</string>
|
<string name="old_android_expiry_date_reached">Briar は Android 4 では動作しなくなりました。\n新しい端末にBriarをインストールしてください。</string>
|
||||||
<string name="old_android_delete_account">下のボタンをタップして、この端末からあなたのアカウントを削除できます。</string>
|
<string name="old_android_delete_account">下のボタンをタップして、この端末からあなたのアカウントを削除できます。</string>
|
||||||
<string name="delete_account_button">アカウントを削除</string>
|
<string name="delete_account_button">アカウントを削除</string>
|
||||||
<string name="startup_open_database">データベースの復号化中…</string>
|
<string name="startup_open_database">データベースの復号化中…</string>
|
||||||
@@ -69,36 +69,36 @@
|
|||||||
<string name="lock_button">アプリをロック</string>
|
<string name="lock_button">アプリをロック</string>
|
||||||
<string name="settings_button">設定</string>
|
<string name="settings_button">設定</string>
|
||||||
<string name="sign_out_button">サインアウト</string>
|
<string name="sign_out_button">サインアウト</string>
|
||||||
<string name="transports_onboarding_text">ここにタップすると、Briarがあなたの連絡先に接続する方法を制御できます。</string>
|
<string name="transports_onboarding_text">ここにタップすると、Briar があなたの連絡先に接続する方法を制御できます。</string>
|
||||||
<!--Transports: Tor-->
|
<!--Transports: Tor-->
|
||||||
<string name="transport_tor">インターネット</string>
|
<string name="transport_tor">インターネット</string>
|
||||||
<string name="tor_device_status_online_wifi">電話機はWi-Fiでインターネットにアクセスできます</string>
|
<string name="tor_device_status_online_wifi">電話機はWi-Fiでインターネットにアクセスできます</string>
|
||||||
<string name="tor_device_status_online_mobile">電話機はモバイル データでインターネットにアクセスできます</string>
|
<string name="tor_device_status_online_mobile">電話機はモバイル データでインターネットにアクセスできます</string>
|
||||||
<string name="tor_device_status_offline">電話機がインターネットに接続できません</string>
|
<string name="tor_device_status_offline">電話機がインターネットに接続できません</string>
|
||||||
<string name="tor_plugin_status_enabling">Briarはインターネットに接続中です…</string>
|
<string name="tor_plugin_status_enabling">Briar はインターネットに接続中です…</string>
|
||||||
<string name="tor_plugin_status_active">Briarはインターネットに接続されました</string>
|
<string name="tor_plugin_status_active">Briar はインターネットに接続されました</string>
|
||||||
<string name="tor_plugin_status_inactive">Briarはインターネットに接続できません</string>
|
<string name="tor_plugin_status_inactive">Briar はインターネットに接続できません</string>
|
||||||
<string name="tor_plugin_status_disabled">Briarはインターネットを使用しないように設定されています</string>
|
<string name="tor_plugin_status_disabled">Briar はインターネットを使用しないように設定されています</string>
|
||||||
<string name="tor_plugin_status_disabled_mobile_data">Briarはモバイルデータを使用しないように設定されています</string>
|
<string name="tor_plugin_status_disabled_mobile_data">Briar はモバイルデータを使用しないように設定されています</string>
|
||||||
<string name="tor_plugin_status_disabled_battery">Briarはバッテリー駆動時にインターネットを使用しないように設定されています</string>
|
<string name="tor_plugin_status_disabled_battery">Briar はバッテリー駆動時にインターネットを使用しないように設定されています</string>
|
||||||
<string name="tor_plugin_status_disabled_country_blocked">Briarはこの国でインターネットを使わないように設定されています</string>
|
<string name="tor_plugin_status_disabled_country_blocked">Briar はこの国でインターネットを使わないように設定されています</string>
|
||||||
<!--Transports: Wi-Fi-->
|
<!--Transports: Wi-Fi-->
|
||||||
<string name="transport_lan">Wi-Fi</string>
|
<string name="transport_lan">Wi-Fi</string>
|
||||||
<string name="transport_lan_long">同じ Wi-Fi ネットワーク</string>
|
<string name="transport_lan_long">同じ Wi-Fi ネットワーク</string>
|
||||||
<string name="lan_device_status_on">電話機は Wi-Fi に接続されました</string>
|
<string name="lan_device_status_on">電話機は Wi-Fi に接続されました</string>
|
||||||
<string name="lan_device_status_off">電話機はWi-Fiに接続されていません</string>
|
<string name="lan_device_status_off">電話機はWi-Fiに接続されていません</string>
|
||||||
<string name="lan_plugin_status_enabling">BriarはWi-Fiネットワークに接続中です…</string>
|
<string name="lan_plugin_status_enabling">Briar は Wi-Fi ネットワークに接続中です…</string>
|
||||||
<string name="lan_plugin_status_active">BriarはWi-Fiネットワークに接続されました</string>
|
<string name="lan_plugin_status_active">Briar は Wi-Fi ネットワークに接続されました</string>
|
||||||
<string name="lan_plugin_status_inactive">BriarはWi-Fiネットワークに接続できません</string>
|
<string name="lan_plugin_status_inactive">Briar は Wi-Fi ネットワークに接続できません</string>
|
||||||
<string name="lan_plugin_status_disabled">BriarはWi-Fiネットワークを使用しないように設定されています</string>
|
<string name="lan_plugin_status_disabled">Briar は Wi-Fi ネットワークを使用しないように設定されています</string>
|
||||||
<!--Transports: Bluetooth-->
|
<!--Transports: Bluetooth-->
|
||||||
<string name="transport_bt">Bluetooth</string>
|
<string name="transport_bt">Bluetooth</string>
|
||||||
<string name="bt_device_status_on">携帯電話の Bluetooth はオンになっています</string>
|
<string name="bt_device_status_on">携帯電話の Bluetooth はオンになっています</string>
|
||||||
<string name="bt_device_status_off">携帯電話の Bluetooth はオフにされました</string>
|
<string name="bt_device_status_off">携帯電話の Bluetooth はオフにされました</string>
|
||||||
<string name="bt_plugin_status_enabling">BriarはBluetoothに接続中です…</string>
|
<string name="bt_plugin_status_enabling">Briar は Bluetooth に接続中です…</string>
|
||||||
<string name="bt_plugin_status_active">BriarはBluetoothに接続しました</string>
|
<string name="bt_plugin_status_active">Briar は Bluetooth に接続しました</string>
|
||||||
<string name="bt_plugin_status_inactive">BriarはBluetoothに接続できません</string>
|
<string name="bt_plugin_status_inactive">Briar は Bluetooth に接続できません</string>
|
||||||
<string name="bt_plugin_status_disabled">BriarはBluetoothを使用しないように設定されています</string>
|
<string name="bt_plugin_status_disabled">Briar は Bluetooth を使用しないように設定されています</string>
|
||||||
<!--Notifications-->
|
<!--Notifications-->
|
||||||
<string name="reminder_notification_title">Briarからサインアウト</string>
|
<string name="reminder_notification_title">Briarからサインアウト</string>
|
||||||
<string name="reminder_notification_text">タップして再ログインします。</string>
|
<string name="reminder_notification_text">タップして再ログインします。</string>
|
||||||
@@ -323,7 +323,6 @@
|
|||||||
<string name="connect_via_bluetooth_intro">Bluetooth接続が自動的に行われない場合は、この画面を使って手動で接続することができます。\n\nこの機能を利用するには、あなたの連絡先が近くにある必要があります。\n\nあなたと連絡先が同時に\"開始\"を押してください。</string>
|
<string name="connect_via_bluetooth_intro">Bluetooth接続が自動的に行われない場合は、この画面を使って手動で接続することができます。\n\nこの機能を利用するには、あなたの連絡先が近くにある必要があります。\n\nあなたと連絡先が同時に\"開始\"を押してください。</string>
|
||||||
<string name="connect_via_bluetooth_already_discovering">既にBluetooth経由での接続を試行中です。すぐに再試行してください。</string>
|
<string name="connect_via_bluetooth_already_discovering">既にBluetooth経由での接続を試行中です。すぐに再試行してください。</string>
|
||||||
<string name="connect_via_bluetooth_no_location_permission">位置情報の権限なくして続行不可能</string>
|
<string name="connect_via_bluetooth_no_location_permission">位置情報の権限なくして続行不可能</string>
|
||||||
<string name="connect_via_bluetooth_no_bluetooth_permission">付近の端末の権限なくして続行不可能</string>
|
|
||||||
<string name="connect_via_bluetooth_start">Bluetooth経由で接続中…</string>
|
<string name="connect_via_bluetooth_start">Bluetooth経由で接続中…</string>
|
||||||
<string name="connect_via_bluetooth_success">Bluetooth経由で接続に成功</string>
|
<string name="connect_via_bluetooth_success">Bluetooth経由で接続に成功</string>
|
||||||
<string name="connect_via_bluetooth_error">Bluetooth経由で接続不可能。</string>
|
<string name="connect_via_bluetooth_error">Bluetooth経由で接続不可能。</string>
|
||||||
@@ -349,9 +348,9 @@
|
|||||||
<string name="groups_member_created">%sがグループを作成しました</string>
|
<string name="groups_member_created">%sがグループを作成しました</string>
|
||||||
<string name="groups_member_joined_you">グループに参加しました</string>
|
<string name="groups_member_joined_you">グループに参加しました</string>
|
||||||
<string name="groups_member_joined">%sがグループに参加しました</string>
|
<string name="groups_member_joined">%sがグループに参加しました</string>
|
||||||
<string name="groups_leave">グループを脱退</string>
|
<string name="groups_leave">グループをやめる</string>
|
||||||
<string name="groups_leave_dialog_title">グループをやめる確認</string>
|
<string name="groups_leave_dialog_title">グループをやめる確認</string>
|
||||||
<string name="groups_leave_dialog_message">このグループを脱退してもよろしいですか?</string>
|
<string name="groups_leave_dialog_message">このグループをやめてもよろしいですか?</string>
|
||||||
<string name="groups_dissolve">グループを削除</string>
|
<string name="groups_dissolve">グループを削除</string>
|
||||||
<string name="groups_dissolve_dialog_title">グループの削除の確認</string>
|
<string name="groups_dissolve_dialog_title">グループの削除の確認</string>
|
||||||
<string name="groups_dissolve_dialog_message">このグループを削除してもよろしいですか?\n\nグループを削除すると、他のすべてのメンバーは会話を続けることができなくなり、最新のメッセージは受信できなくなります。</string>
|
<string name="groups_dissolve_dialog_message">このグループを削除してもよろしいですか?\n\nグループを削除すると、他のすべてのメンバーは会話を続けることができなくなり、最新のメッセージは受信できなくなります。</string>
|
||||||
@@ -395,10 +394,10 @@
|
|||||||
<string name="forum_new_message_hint">新しい投稿</string>
|
<string name="forum_new_message_hint">新しい投稿</string>
|
||||||
<string name="forum_message_reply_hint">新しい返信</string>
|
<string name="forum_message_reply_hint">新しい返信</string>
|
||||||
<string name="btn_reply">返信</string>
|
<string name="btn_reply">返信</string>
|
||||||
<string name="forum_leave">フォーラムを脱退</string>
|
<string name="forum_leave">フォーラムをやめる</string>
|
||||||
<string name="dialog_title_leave_forum">フォーラムをやめる確認</string>
|
<string name="dialog_title_leave_forum">フォーラムをやめる確認</string>
|
||||||
<string name="dialog_message_leave_forum">このフォーラムを脱退してもよろしいですか?\n\nこのフォーラムで共有した連絡先は更新の受信を停止します。</string>
|
<string name="dialog_message_leave_forum">このフォーラムをやめてもよろしいですか?\n\nこのフォーラムで共有した連絡先は更新の受信を停止します。</string>
|
||||||
<string name="dialog_button_leave">脱退</string>
|
<string name="dialog_button_leave">脱退する</string>
|
||||||
<string name="forum_left_toast">フォーラムをやめました</string>
|
<string name="forum_left_toast">フォーラムをやめました</string>
|
||||||
<!--Forum Sharing-->
|
<!--Forum Sharing-->
|
||||||
<string name="forum_share_button">フォーラムを共有</string>
|
<string name="forum_share_button">フォーラムを共有</string>
|
||||||
@@ -417,10 +416,6 @@
|
|||||||
<string name="forum_declined_toast">招待を辞退しました</string>
|
<string name="forum_declined_toast">招待を辞退しました</string>
|
||||||
<string name="shared_by_format">%sによって共有されました。</string>
|
<string name="shared_by_format">%sによって共有されました。</string>
|
||||||
<string name="forum_invitation_already_sharing">既に共有しています</string>
|
<string name="forum_invitation_already_sharing">既に共有しています</string>
|
||||||
<string name="forum_invitation_already_invited">招待は既に送信しました</string>
|
|
||||||
<string name="forum_invitation_invite_received">招待は既に受信されました</string>
|
|
||||||
<string name="forum_invitation_not_supported">この連絡先によってサポートされていません</string>
|
|
||||||
<string name="forum_invitation_error">エラー。これはバグか、そうでなければ、あなたの誤りです</string>
|
|
||||||
<string name="forum_invitation_response_accepted_sent">%sからのフォーラムへの招待を受け入れました。</string>
|
<string name="forum_invitation_response_accepted_sent">%sからのフォーラムへの招待を受け入れました。</string>
|
||||||
<string name="forum_invitation_response_declined_sent">%sからのフォーラムへの招待を辞退しました。</string>
|
<string name="forum_invitation_response_declined_sent">%sからのフォーラムへの招待を辞退しました。</string>
|
||||||
<string name="forum_invitation_response_declined_auto">%sからのフォーラムへの招待は自動的に辞退されました。</string>
|
<string name="forum_invitation_response_declined_auto">%sからのフォーラムへの招待は自動的に辞退されました。</string>
|
||||||
@@ -470,9 +465,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">RSSフィードをインポート</string>
|
<string name="blogs_rss_feeds_import">RSSフィードをインポート</string>
|
||||||
<string name="blogs_rss_feeds_import_button">インポート</string>
|
<string name="blogs_rss_feeds_import_button">インポート</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">RSSフィードのURLを入力してください</string>
|
<string name="blogs_rss_feeds_import_hint">RSSフィードのURLを入力してください</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">RSSフィードをインポート中…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">申し訳ありません! フィードのインポート中にエラーが発生しました。</string>
|
<string name="blogs_rss_feeds_import_error">申し訳ありません! フィードのインポート中にエラーが発生しました。</string>
|
||||||
<string name="blogs_rss_feeds_import_title">ファイルからフィードをインポート</string>
|
<string name="blogs_rss_feeds_import_exists">そのフィードは既にインポートされています。</string>
|
||||||
<string name="blogs_rss_feeds">RSSフィード</string>
|
<string name="blogs_rss_feeds">RSSフィード</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">インポート済み:</string>
|
<string name="blogs_rss_feeds_manage_imported">インポート済み:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">著者:</string>
|
<string name="blogs_rss_feeds_manage_author">著者:</string>
|
||||||
@@ -579,7 +573,7 @@
|
|||||||
<string name="mailbox_setup_title">メールボックスのセットアップ</string>
|
<string name="mailbox_setup_title">メールボックスのセットアップ</string>
|
||||||
<string name="mailbox_setup_intro">メールボックスはあなたがオフラインの間、連絡先があなたにメッセージを送信することを有効にします。メールボックスはあなたがオンラインになるまで、メッセージを受信し保管します。\n
|
<string name="mailbox_setup_intro">メールボックスはあなたがオフラインの間、連絡先があなたにメッセージを送信することを有効にします。メールボックスはあなたがオンラインになるまで、メッセージを受信し保管します。\n
|
||||||
\n予備端末上にBriarのメールボックスアプリをインストールできます。それを電源とWi-Fiに接続し、常時オンラインにしてください。</string>
|
\n予備端末上にBriarのメールボックスアプリをインストールできます。それを電源とWi-Fiに接続し、常時オンラインにしてください。</string>
|
||||||
<string name="mailbox_setup_download">最初に、Google PlayまたはBriarをダウンロードしたどこかで\"BriarMailbox\"を検索して、他の端末上にメールボックスアプリをインストールします。\n
|
<string name="mailbox_setup_download">最初に、Google PlayまたはBriarをダウンロードしたどこかで\"Briar Mailbox\"を検索して、他の端末上にメールボックスアプリをインストールします。\n
|
||||||
\nそして、メールボックスアプリによって表示されるQRコードを読み取って、Briarとあなたのメールボックス結びつけます。</string>
|
\nそして、メールボックスアプリによって表示されるQRコードを読み取って、Briarとあなたのメールボックス結びつけます。</string>
|
||||||
<string name="mailbox_setup_download_link">ダウンロードリンクを共有</string>
|
<string name="mailbox_setup_download_link">ダウンロードリンクを共有</string>
|
||||||
<string name="mailbox_setup_button_scan">メールボックスのQRコードを読み取る</string>
|
<string name="mailbox_setup_button_scan">メールボックスのQRコードを読み取る</string>
|
||||||
@@ -591,15 +585,15 @@
|
|||||||
<string name="mailbox_qr_code_too_new">読み取ったQRコードは、新しいバージョンのBriarメールボックスから生じました。\n\nBriarを最新版にアップグレードしてから、もう一度お試しください。</string>
|
<string name="mailbox_qr_code_too_new">読み取ったQRコードは、新しいバージョンのBriarメールボックスから生じました。\n\nBriarを最新版にアップグレードしてから、もう一度お試しください。</string>
|
||||||
<string name="contact_qr_code_for_mailbox">読み取ったQRコードは、Briarの連絡先を追加するためのものです。\n\n連絡先を追加したいならば、連絡先一覧に行き、+アイコンをタップしてください。</string>
|
<string name="contact_qr_code_for_mailbox">読み取ったQRコードは、Briarの連絡先を追加するためのものです。\n\n連絡先を追加したいならば、連絡先一覧に行き、+アイコンをタップしてください。</string>
|
||||||
<string name="mailbox_setup_qr_code_wrong_description">読み取ったQRコードは、Briarメールボックスから生じたものではありません。メールボックス端末上のBriarメールボックスアプリを開き、提示されたQRコードを読み取ってください。</string>
|
<string name="mailbox_setup_qr_code_wrong_description">読み取ったQRコードは、Briarメールボックスから生じたものではありません。メールボックス端末上のBriarメールボックスアプリを開き、提示されたQRコードを読み取ってください。</string>
|
||||||
<string name="mailbox_setup_already_paired_title">メールボックスは既にリンクされています</string>
|
<string name="mailbox_setup_already_paired_title">メールボックスは既に結びつけられています</string>
|
||||||
<string name="mailbox_setup_already_paired_description">あなたの端末上のメールボックスのリンクを解き、再試行してください。</string>
|
<string name="mailbox_setup_already_paired_description">あなたの端末上のメールボックスの結びつけを解き、再試行してください。</string>
|
||||||
<string name="mailbox_setup_io_error_title">接続できません</string>
|
<string name="mailbox_setup_io_error_title">接続できません</string>
|
||||||
<string name="mailbox_setup_io_error_description">双方の端末がインターネットに接続されていることを確かにして、再試行してください。</string>
|
<string name="mailbox_setup_io_error_description">双方の端末がインターネットに接続されていることを確かにして、再試行してください。</string>
|
||||||
<string name="mailbox_setup_assertion_error_title">メールボックスのエラー</string>
|
<string name="mailbox_setup_assertion_error_title">メールボックスのエラー</string>
|
||||||
<string name="mailbox_setup_assertion_error_description">もし問題が続くのであれば、Briarアプリ経由で(匿名データ付きの)フィードバックを送信してください。</string>
|
<string name="mailbox_setup_assertion_error_description">もし問題が続くのであれば、Briarアプリ経由で(匿名データ付きの)フィードバックを送信してください。</string>
|
||||||
<string name="mailbox_setup_camera_error_description">カメラにアクセスできません。端末を再起動してから、もう一度試してみてください。</string>
|
<string name="mailbox_setup_camera_error_description">カメラにアクセスできません。端末を再起動してから、もう一度試してみてください。</string>
|
||||||
<string name="mailbox_setup_paired_title">接続済み</string>
|
<string name="mailbox_setup_paired_title">接続済み</string>
|
||||||
<string name="mailbox_setup_paired_description">あなたのメールボックスはBriarとのリンクに成功しています。\n
|
<string name="mailbox_setup_paired_description">あなたのメールボックスはBriarとの結びつけられるのに成功しています。\n
|
||||||
メールボックスを電源とW-Fiに接続して、常時オンラインにしてください。</string>
|
メールボックスを電源とW-Fiに接続して、常時オンラインにしてください。</string>
|
||||||
<string name="tor_offline_title">オフライン</string>
|
<string name="tor_offline_title">オフライン</string>
|
||||||
<string name="tor_offline_description">この端末がオンラインかつインターネットへの接続が許可されていること確かにしてください。\n
|
<string name="tor_offline_description">この端末がオンラインかつインターネットへの接続が許可されていること確かにしてください。\n
|
||||||
@@ -639,7 +633,7 @@
|
|||||||
<string name="mailbox_error_wizard_answer1_1">メールボックスの設定方法が表示される</string>
|
<string name="mailbox_error_wizard_answer1_1">メールボックスの設定方法が表示される</string>
|
||||||
<string name="mailbox_error_wizard_answer1_2">QRコードが表示される</string>
|
<string name="mailbox_error_wizard_answer1_2">QRコードが表示される</string>
|
||||||
<string name="mailbox_error_wizard_answer1_3">「メールボックスは実行中」と表示される</string>
|
<string name="mailbox_error_wizard_answer1_3">「メールボックスは実行中」と表示される</string>
|
||||||
<string name="mailbox_error_wizard_answer1_4">「端末がオフライン」と表示されます</string>
|
<string name="mailbox_error_wizard_answer1_4">「デバイスがオフライン」と表示されます</string>
|
||||||
<string name="mailbox_error_wizard_info1_1_1">以下のボタンでメールボックスのリンクを解除し、メールボックスの端末の指示に従って再度リンクしてください。</string>
|
<string name="mailbox_error_wizard_info1_1_1">以下のボタンでメールボックスのリンクを解除し、メールボックスの端末の指示に従って再度リンクしてください。</string>
|
||||||
<string name="mailbox_error_wizard_info_1_1_2">以下のボタンでメールボックスのリンクを解除し、QRコードを読み取って再度リンクしてください。</string>
|
<string name="mailbox_error_wizard_info_1_1_2">以下のボタンでメールボックスのリンクを解除し、QRコードを読み取って再度リンクしてください。</string>
|
||||||
<string name="mailbox_error_wizard_info1_1_3">以下のボタンを使用して、Briarとメールボックスの間での接続を確認してください。\n\n
|
<string name="mailbox_error_wizard_info1_1_3">以下のボタンを使用して、Briarとメールボックスの間での接続を確認してください。\n\n
|
||||||
@@ -651,7 +645,7 @@
|
|||||||
<string name="mailbox_error_wizard_info3">以下のボタンを使用してメールボックスをリンク解除してください。\n\n古いメールボックスをリンク解除した後、いつでも新しいメールボックスをセットアップできます。</string>
|
<string name="mailbox_error_wizard_info3">以下のボタンを使用してメールボックスをリンク解除してください。\n\n古いメールボックスをリンク解除した後、いつでも新しいメールボックスをセットアップできます。</string>
|
||||||
<!--About-->
|
<!--About-->
|
||||||
<string name="about_title">Tor Project について</string>
|
<string name="about_title">Tor Project について</string>
|
||||||
<string name="briar_version">Briarバージョン: %s</string>
|
<string name="briar_version">Briar バージョン: %s</string>
|
||||||
<string name="tor_version">Tor バージョン: %s</string>
|
<string name="tor_version">Tor バージョン: %s</string>
|
||||||
<string name="links">リンク</string>
|
<string name="links">リンク</string>
|
||||||
<string name="briar_website">\u2022 <a href="">ウェブサイト</a></string>
|
<string name="briar_website">\u2022 <a href="">ウェブサイト</a></string>
|
||||||
@@ -783,7 +777,7 @@
|
|||||||
<string name="hotspot_manual_site_address">アドレス(URL)</string>
|
<string name="hotspot_manual_site_address">アドレス(URL)</string>
|
||||||
<string name="hotspot_qr_site">あなたの電話機はWi-Fiホットスポットを提供しています。ホットスポットに接続された人は、このQRコードを読み取って、Briarをダウンロードできます。</string>
|
<string name="hotspot_qr_site">あなたの電話機はWi-Fiホットスポットを提供しています。ホットスポットに接続された人は、このQRコードを読み取って、Briarをダウンロードできます。</string>
|
||||||
<!--e.g. Download Briar 1.2.20-->
|
<!--e.g. Download Briar 1.2.20-->
|
||||||
<string name="website_download_title_1">Briar%sをダウンロード</string>
|
<string name="website_download_title_1">Briar %sをダウンロード</string>
|
||||||
<string name="website_download_intro_1">近くの誰かが、あなたとBriarを共有しました。</string>
|
<string name="website_download_intro_1">近くの誰かが、あなたとBriarを共有しました。</string>
|
||||||
<string name="website_download_button">Briarをダウンロード</string>
|
<string name="website_download_button">Briarをダウンロード</string>
|
||||||
<string name="website_download_outro">ダウンロードが完了した後に、ダウンロードしたファイルを開いて、インストールしてください。</string>
|
<string name="website_download_outro">ダウンロードが完了した後に、ダウンロードしたファイルを開いて、インストールしてください。</string>
|
||||||
|
|||||||
@@ -477,6 +477,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">იმპორტი</string>
|
<string name="blogs_rss_feeds_import_button">იმპორტი</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">შეიყვანეთ RSS არხის URL</string>
|
<string name="blogs_rss_feeds_import_hint">შეიყვანეთ RSS არხის URL</string>
|
||||||
<string name="blogs_rss_feeds_import_error">ვწუხვართ! არხის იმპორტირებისას შეცდომა წარმოიშვა.</string>
|
<string name="blogs_rss_feeds_import_error">ვწუხვართ! არხის იმპორტირებისას შეცდომა წარმოიშვა.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">არხი უკვე იმპორტირებულია.</string>
|
||||||
<string name="blogs_rss_feeds">RSS არხები</string>
|
<string name="blogs_rss_feeds">RSS არხები</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">იმპორტირებული:</string>
|
<string name="blogs_rss_feeds_manage_imported">იმპორტირებული:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">ავტორი:</string>
|
<string name="blogs_rss_feeds_manage_author">ავტორი:</string>
|
||||||
|
|||||||
@@ -313,8 +313,6 @@
|
|||||||
<string name="duplicate_link_dialog_text_3">%1$s ir %2$s išsiuntė jums tą pačią nuorodą.\n\nGali būti, kad vienas iš šių asmenų bando sužinoti kas yra jūsų adresatų sąraše.\n\nNesakykite šiems asmenims, kad gavote tokią pačią nuorodą iš kito asmens.</string>
|
<string name="duplicate_link_dialog_text_3">%1$s ir %2$s išsiuntė jums tą pačią nuorodą.\n\nGali būti, kad vienas iš šių asmenų bando sužinoti kas yra jūsų adresatų sąraše.\n\nNesakykite šiems asmenims, kad gavote tokią pačią nuorodą iš kito asmens.</string>
|
||||||
<string name="pending_contact_updated_toast">Laukiantis adresatas atnaujintas</string>
|
<string name="pending_contact_updated_toast">Laukiantis adresatas atnaujintas</string>
|
||||||
<!--Peer trust levels-->
|
<!--Peer trust levels-->
|
||||||
<string name="peer_trust_level_ourselves">Aš</string>
|
|
||||||
<string name="peer_trust_level_stranger">Nepažįstamasis</string>
|
|
||||||
<!--Introductions-->
|
<!--Introductions-->
|
||||||
<string name="introduction_onboarding_title">Supažindinkite savo adresatus</string>
|
<string name="introduction_onboarding_title">Supažindinkite savo adresatus</string>
|
||||||
<string name="introduction_menu_item">Supažindinti</string>
|
<string name="introduction_menu_item">Supažindinti</string>
|
||||||
@@ -444,9 +442,6 @@
|
|||||||
<string name="forum_declined_toast">Pakvietimas atmestas</string>
|
<string name="forum_declined_toast">Pakvietimas atmestas</string>
|
||||||
<string name="shared_by_format">Bendrina %s</string>
|
<string name="shared_by_format">Bendrina %s</string>
|
||||||
<string name="forum_invitation_already_sharing">Jau bendrinama</string>
|
<string name="forum_invitation_already_sharing">Jau bendrinama</string>
|
||||||
<string name="forum_invitation_already_invited">Pakvietimas jau išsiųstas</string>
|
|
||||||
<string name="forum_invitation_invite_received">Pakvietimas jau gautas</string>
|
|
||||||
<string name="forum_invitation_error">Klaida. Tai yra triktis ir ne jūsų kaltė</string>
|
|
||||||
<string name="forum_invitation_response_accepted_sent">Jūs priėmėte pakvietimą į forumą iš %s.</string>
|
<string name="forum_invitation_response_accepted_sent">Jūs priėmėte pakvietimą į forumą iš %s.</string>
|
||||||
<string name="forum_invitation_response_declined_sent">Jūs atmetėte pakvietimą į forumą iš %s.</string>
|
<string name="forum_invitation_response_declined_sent">Jūs atmetėte pakvietimą į forumą iš %s.</string>
|
||||||
<string name="forum_invitation_response_declined_auto">Pakvietimas į forumą nuo %s buvo automatiškai atmestas.</string>
|
<string name="forum_invitation_response_declined_auto">Pakvietimas į forumą nuo %s buvo automatiškai atmestas.</string>
|
||||||
@@ -499,9 +494,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">Importuoti RSS kanalą</string>
|
<string name="blogs_rss_feeds_import">Importuoti RSS kanalą</string>
|
||||||
<string name="blogs_rss_feeds_import_button">Importuoti</string>
|
<string name="blogs_rss_feeds_import_button">Importuoti</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Įveskite RSS kanalo URL</string>
|
<string name="blogs_rss_feeds_import_hint">Įveskite RSS kanalo URL</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">Importuojamas RSS kanalas…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">Atleiskite! Importuojant jūsų kanalą, įvyko klaida.</string>
|
<string name="blogs_rss_feeds_import_error">Atleiskite! Importuojant jūsų kanalą, įvyko klaida.</string>
|
||||||
<string name="blogs_rss_feeds_import_title">Importuoti kanalą iš failo</string>
|
<string name="blogs_rss_feeds_import_exists">Tas kanalas jau yra importuotas.</string>
|
||||||
<string name="blogs_rss_feeds">RSS kanalai</string>
|
<string name="blogs_rss_feeds">RSS kanalai</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importuota:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importuota:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autorius:</string>
|
<string name="blogs_rss_feeds_manage_author">Autorius:</string>
|
||||||
@@ -611,7 +605,6 @@
|
|||||||
<string name="mailbox_setup_download_link">Bendrinti atsisiuntimo nuorodą</string>
|
<string name="mailbox_setup_download_link">Bendrinti atsisiuntimo nuorodą</string>
|
||||||
<string name="mailbox_setup_button_scan">Skenuoti pašto dėžutės QR kodą</string>
|
<string name="mailbox_setup_button_scan">Skenuoti pašto dėžutės QR kodą</string>
|
||||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||||
<string name="mailbox_setup_connecting_info">Tai gali užtrukti iki %1s</string>
|
|
||||||
<string name="mailbox_setup_already_paired_title">Pašto dėžutė jau susieta</string>
|
<string name="mailbox_setup_already_paired_title">Pašto dėžutė jau susieta</string>
|
||||||
<string name="mailbox_setup_io_error_title">Nepavyko prisijungti</string>
|
<string name="mailbox_setup_io_error_title">Nepavyko prisijungti</string>
|
||||||
<string name="mailbox_setup_io_error_description">Įsitikinkite, kad abu įrenginiai yra prisijungę prie interneto ir bandykite dar kartą.</string>
|
<string name="mailbox_setup_io_error_description">Įsitikinkite, kad abu įrenginiai yra prisijungę prie interneto ir bandykite dar kartą.</string>
|
||||||
@@ -648,7 +641,6 @@
|
|||||||
<string name="briar_changelog">\u2022 <a href="">Keitinių žurnalas</a></string>
|
<string name="briar_changelog">\u2022 <a href="">Keitinių žurnalas</a></string>
|
||||||
<string name="briar_privacy_policy">\u2022 <a href="">Privatumo politika</a></string>
|
<string name="briar_privacy_policy">\u2022 <a href="">Privatumo politika</a></string>
|
||||||
<!--Here translators can add their names or Transifex usernames(eg "Thanks to all the contributors at the Localization Lab, especially Tom, Matthew and Jerry")-->
|
<!--Here translators can add their names or Transifex usernames(eg "Thanks to all the contributors at the Localization Lab, especially Tom, Matthew and Jerry")-->
|
||||||
<string name="translator_thanks">Dėkojame talkininkams iš Localization Lab, ypač Moo už vertimą į lietuvių kalbą</string>
|
|
||||||
<!--Conversation Settings-->
|
<!--Conversation Settings-->
|
||||||
<string name="disappearing_messages_title">Išnykstančios žinutės</string>
|
<string name="disappearing_messages_title">Išnykstančios žinutės</string>
|
||||||
<string name="disappearing_messages_explanation_long">Įjungus šį nustatymą, naujos žinutės
|
<string name="disappearing_messages_explanation_long">Įjungus šį nustatymą, naujos žinutės
|
||||||
|
|||||||
@@ -460,6 +460,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">တင်သွင်းမည်</string>
|
<string name="blogs_rss_feeds_import_button">တင်သွင်းမည်</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">RSS သတင်းပို့စ်အလွှာ၏ URL ရိုက်ထည့်ပေးပါ</string>
|
<string name="blogs_rss_feeds_import_hint">RSS သတင်းပို့စ်အလွှာ၏ URL ရိုက်ထည့်ပေးပါ</string>
|
||||||
<string name="blogs_rss_feeds_import_error">ဝမ်းနည်းပါသည်! သင့် သတင်းပို့စ်အလွှာအား တင်သွင်းရာတွင် ပျက်ကွက်မှု ဖြစ်ခဲ့ပါသည်။</string>
|
<string name="blogs_rss_feeds_import_error">ဝမ်းနည်းပါသည်! သင့် သတင်းပို့စ်အလွှာအား တင်သွင်းရာတွင် ပျက်ကွက်မှု ဖြစ်ခဲ့ပါသည်။</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Feed ကို တင်ပို့ပြီး ဖြစ်သည်။</string>
|
||||||
<string name="blogs_rss_feeds">RSS သတင်းလွှာများ</string>
|
<string name="blogs_rss_feeds">RSS သတင်းလွှာများ</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">တင်သွင်းထားသော</string>
|
<string name="blogs_rss_feeds_manage_imported">တင်သွင်းထားသော</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">စာရေးဆရာ -</string>
|
<string name="blogs_rss_feeds_manage_author">စာရေးဆရာ -</string>
|
||||||
|
|||||||
@@ -477,6 +477,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">Importer</string>
|
<string name="blogs_rss_feeds_import_button">Importer</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Skriv inn nettadresse for RSS-strøm</string>
|
<string name="blogs_rss_feeds_import_hint">Skriv inn nettadresse for RSS-strøm</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Vi beklager! Feil under importering av strøm.</string>
|
<string name="blogs_rss_feeds_import_error">Vi beklager! Feil under importering av strøm.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Den feed\'en er importert allerede</string>
|
||||||
<string name="blogs_rss_feeds">RSS-feed\'er</string>
|
<string name="blogs_rss_feeds">RSS-feed\'er</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importert:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importert:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Forfatter:</string>
|
<string name="blogs_rss_feeds_manage_author">Forfatter:</string>
|
||||||
|
|||||||
@@ -244,7 +244,6 @@
|
|||||||
<string name="menu_contact">Kontakt</string>
|
<string name="menu_contact">Kontakt</string>
|
||||||
<!--Adding Contacts-->
|
<!--Adding Contacts-->
|
||||||
<string name="add_contact_title">Dodaj kontakt w pobliżu</string>
|
<string name="add_contact_title">Dodaj kontakt w pobliżu</string>
|
||||||
<string name="add_contact_error_two_way">Czy oboje skanowaliście nawzajem swoje kody QR?</string>
|
|
||||||
<string name="face_to_face">Musisz spotkać się z osobą którą chcesz dodać jako kontakt.\n\nTo uniemożliwi komukolwiek udawanie Ciebie lub czytanie Twoich wiadomości w przyszłości.</string>
|
<string name="face_to_face">Musisz spotkać się z osobą którą chcesz dodać jako kontakt.\n\nTo uniemożliwi komukolwiek udawanie Ciebie lub czytanie Twoich wiadomości w przyszłości.</string>
|
||||||
<string name="continue_button">Kontynuuj</string>
|
<string name="continue_button">Kontynuuj</string>
|
||||||
<string name="try_again_button">Spróbuj ponownie</string>
|
<string name="try_again_button">Spróbuj ponownie</string>
|
||||||
@@ -260,7 +259,6 @@
|
|||||||
<string name="authenticating_with_device">Autoryzowanie z urządzeniem\u2026</string>
|
<string name="authenticating_with_device">Autoryzowanie z urządzeniem\u2026</string>
|
||||||
<string name="connection_error_title">Nie udało się połączyć z kontaktem</string>
|
<string name="connection_error_title">Nie udało się połączyć z kontaktem</string>
|
||||||
<string name="connection_error_feedback">Jeśli problem będzie występować dalej, proszę <a href="feedback">wysłać opinię</a> aby pomóc nam ulepszyć aplikację.</string>
|
<string name="connection_error_feedback">Jeśli problem będzie występować dalej, proszę <a href="feedback">wysłać opinię</a> aby pomóc nam ulepszyć aplikację.</string>
|
||||||
<string name="info_both_must_scan">Oboje musicie skanować nawzajem swoje kody QR</string>
|
|
||||||
<!--Adding Contacts Remotely-->
|
<!--Adding Contacts Remotely-->
|
||||||
<string name="add_contact_remotely_title_case">Dodaj Kontakt na odległość</string>
|
<string name="add_contact_remotely_title_case">Dodaj Kontakt na odległość</string>
|
||||||
<string name="add_contact_nearby_title">Dodaj kontakt w pobliżu</string>
|
<string name="add_contact_nearby_title">Dodaj kontakt w pobliżu</string>
|
||||||
@@ -320,7 +318,6 @@
|
|||||||
<string name="different_person_button">Inna osoba</string>
|
<string name="different_person_button">Inna osoba</string>
|
||||||
<string name="duplicate_link_dialog_text_3">%1$si %2$s wysłał ci ten sam link.\n\nJeden z nich może próbować odkryć, kim są twoje kontakty.\n\nNie mów im, że otrzymałeś ten sam link od kogoś innego.</string>
|
<string name="duplicate_link_dialog_text_3">%1$si %2$s wysłał ci ten sam link.\n\nJeden z nich może próbować odkryć, kim są twoje kontakty.\n\nNie mów im, że otrzymałeś ten sam link od kogoś innego.</string>
|
||||||
<string name="pending_contact_updated_toast">Oczekujący kontakt zaktualizowany</string>
|
<string name="pending_contact_updated_toast">Oczekujący kontakt zaktualizowany</string>
|
||||||
<string name="info_both_must_enter_links">Oboje musicie dodać swoje linki</string>
|
|
||||||
<!--Peer trust levels-->
|
<!--Peer trust levels-->
|
||||||
<string name="peer_trust_level_unverified">Niezweryfikowane kontakty</string>
|
<string name="peer_trust_level_unverified">Niezweryfikowane kontakty</string>
|
||||||
<string name="peer_trust_level_verified">Zweryfikowane kontakty</string>
|
<string name="peer_trust_level_verified">Zweryfikowane kontakty</string>
|
||||||
@@ -354,7 +351,6 @@
|
|||||||
<string name="connect_via_bluetooth_intro">W przypadku gdy połączenia przez Bluetooth nie działają automatycznie, możesz użyć tego ekranu do połączenia ręcznego.\n\nTwój kontakt musi znajdować się w pobliżu, żeby to zadziałało.\n\nTy i Twój kontakt powinniście jednocześnie wcisnąć \"Start\".</string>
|
<string name="connect_via_bluetooth_intro">W przypadku gdy połączenia przez Bluetooth nie działają automatycznie, możesz użyć tego ekranu do połączenia ręcznego.\n\nTwój kontakt musi znajdować się w pobliżu, żeby to zadziałało.\n\nTy i Twój kontakt powinniście jednocześnie wcisnąć \"Start\".</string>
|
||||||
<string name="connect_via_bluetooth_already_discovering">Próba połączenia przez Bluetooth jest już w trakcie. Spróbuj ponownie za chwilę.</string>
|
<string name="connect_via_bluetooth_already_discovering">Próba połączenia przez Bluetooth jest już w trakcie. Spróbuj ponownie za chwilę.</string>
|
||||||
<string name="connect_via_bluetooth_no_location_permission">Nie można kontynuować bez dostępu do lokalizacji</string>
|
<string name="connect_via_bluetooth_no_location_permission">Nie można kontynuować bez dostępu do lokalizacji</string>
|
||||||
<string name="connect_via_bluetooth_no_bluetooth_permission">Nie można kontynuować bez pozwolenia na urządzenia w pobliżu</string>
|
|
||||||
<string name="connect_via_bluetooth_start">Łączenie przez Bluetooth...</string>
|
<string name="connect_via_bluetooth_start">Łączenie przez Bluetooth...</string>
|
||||||
<string name="connect_via_bluetooth_success">Udało się połączyć przez Bluetooth.</string>
|
<string name="connect_via_bluetooth_success">Udało się połączyć przez Bluetooth.</string>
|
||||||
<string name="connect_via_bluetooth_error">Nie można się połączyć przez Bluetooth.</string>
|
<string name="connect_via_bluetooth_error">Nie można się połączyć przez Bluetooth.</string>
|
||||||
@@ -457,10 +453,6 @@
|
|||||||
<string name="forum_declined_toast">Zaproszenie odrzucone</string>
|
<string name="forum_declined_toast">Zaproszenie odrzucone</string>
|
||||||
<string name="shared_by_format">Udostępnione przez %s</string>
|
<string name="shared_by_format">Udostępnione przez %s</string>
|
||||||
<string name="forum_invitation_already_sharing">Już udostępnione</string>
|
<string name="forum_invitation_already_sharing">Już udostępnione</string>
|
||||||
<string name="forum_invitation_already_invited">Wysłano już zaproszenie</string>
|
|
||||||
<string name="forum_invitation_invite_received">Odebrano już zaproszenie</string>
|
|
||||||
<string name="forum_invitation_not_supported">Nie obsługiwane przez ten kontakt</string>
|
|
||||||
<string name="forum_invitation_error">Błąd. Jest to błąd w naszej aplikacji, to nie twoja wina</string>
|
|
||||||
<string name="forum_invitation_response_accepted_sent">Przyjąłeś zaproszenie do forum od %s</string>
|
<string name="forum_invitation_response_accepted_sent">Przyjąłeś zaproszenie do forum od %s</string>
|
||||||
<string name="forum_invitation_response_declined_sent">Odrzuciłeś zaproszenie do forum od %s</string>
|
<string name="forum_invitation_response_declined_sent">Odrzuciłeś zaproszenie do forum od %s</string>
|
||||||
<string name="forum_invitation_response_declined_auto">Zaproszenie do forum od %s zostało automatycznie odrzucone.</string>
|
<string name="forum_invitation_response_declined_auto">Zaproszenie do forum od %s zostało automatycznie odrzucone.</string>
|
||||||
@@ -513,9 +505,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">Zaimportuj kanał RSS</string>
|
<string name="blogs_rss_feeds_import">Zaimportuj kanał RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_button">Zaimportuj</string>
|
<string name="blogs_rss_feeds_import_button">Zaimportuj</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Wprowadź adres URL do kanału RSS</string>
|
<string name="blogs_rss_feeds_import_hint">Wprowadź adres URL do kanału RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">Importowanie kanału RSS…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">Przepraszamy! Wystąpił błąd podczas importowania twojego kanału RSS</string>
|
<string name="blogs_rss_feeds_import_error">Przepraszamy! Wystąpił błąd podczas importowania twojego kanału RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_title">Importuj kanał z pliku</string>
|
<string name="blogs_rss_feeds_import_exists">Ten feed został już zaimportowany.</string>
|
||||||
<string name="blogs_rss_feeds">Feedy RSS</string>
|
<string name="blogs_rss_feeds">Feedy RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Zaimportowane:</string>
|
<string name="blogs_rss_feeds_manage_imported">Zaimportowane:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
||||||
@@ -627,9 +618,7 @@
|
|||||||
<string name="mailbox_setup_download_link">Udostępnij łącze pobierania</string>
|
<string name="mailbox_setup_download_link">Udostępnij łącze pobierania</string>
|
||||||
<string name="mailbox_setup_button_scan">Zeskanuj kod QR aplikacji Mailbox</string>
|
<string name="mailbox_setup_button_scan">Zeskanuj kod QR aplikacji Mailbox</string>
|
||||||
<string name="permission_camera_qr_denied_body">Odmówiłeś dostępu do aparatu, ale zeskanowanie kodu QR wymaga użycia aparatu.\n\nRozważ przyznanie dostępu.</string>
|
<string name="permission_camera_qr_denied_body">Odmówiłeś dostępu do aparatu, ale zeskanowanie kodu QR wymaga użycia aparatu.\n\nRozważ przyznanie dostępu.</string>
|
||||||
<string name="mailbox_setup_connecting">Łączenie się ze Skrzynką odbiorczą…</string>
|
|
||||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
||||||
<string name="mailbox_setup_connecting_info">Może to potrwać do %1s</string>
|
|
||||||
<string name="mailbox_setup_already_paired_title">Mailbox już podłączony</string>
|
<string name="mailbox_setup_already_paired_title">Mailbox już podłączony</string>
|
||||||
<string name="mailbox_setup_already_paired_description">Odłącz Mailbox na drugim urządzeniu i spróbuj ponownie.</string>
|
<string name="mailbox_setup_already_paired_description">Odłącz Mailbox na drugim urządzeniu i spróbuj ponownie.</string>
|
||||||
<string name="mailbox_setup_io_error_title">Nie udało się połączyć</string>
|
<string name="mailbox_setup_io_error_title">Nie udało się połączyć</string>
|
||||||
@@ -767,15 +756,11 @@ Brak dostępu do aparatu. Spróbuj ponownie, może po ponownym uruchomieniu urz
|
|||||||
<string name="permission_location_request_body">Aby odkryć urządzenia Bluetooth, Briar potrzebuje zezwolenia na dostęp do twojej lokalizacji.\n\nBriar nie przechowuje twojej lokalizacji ani nie udostępnia jej nikomu.</string>
|
<string name="permission_location_request_body">Aby odkryć urządzenia Bluetooth, Briar potrzebuje zezwolenia na dostęp do twojej lokalizacji.\n\nBriar nie przechowuje twojej lokalizacji ani nie udostępnia jej nikomu.</string>
|
||||||
<string name="permission_camera_location_title">Kamera i lokalizacja</string>
|
<string name="permission_camera_location_title">Kamera i lokalizacja</string>
|
||||||
<string name="permission_camera_location_request_body">Aby zeskanować kod QR, Briar potrzebuje dostępu do kamery.\n\nAby odkryć urządzenia Bluetooth, Briar potrzebuje zezwolenia na dostęp do Twojej lokalizacji.\n\nBriar nie przechowuje Twojej lokalizacji ani nie udostępnia jej nikomu.</string>
|
<string name="permission_camera_location_request_body">Aby zeskanować kod QR, Briar potrzebuje dostępu do kamery.\n\nAby odkryć urządzenia Bluetooth, Briar potrzebuje zezwolenia na dostęp do Twojej lokalizacji.\n\nBriar nie przechowuje Twojej lokalizacji ani nie udostępnia jej nikomu.</string>
|
||||||
<string name="permission_camera_bluetooth_title">Aparat i urządzenia w pobliżu</string>
|
|
||||||
<string name="permission_camera_denied_body">Odmówiłeś dostępu do aparatu, lecz dodawanie kontaktów wymaga jego użycia.\n\nProszę rozważyć udzielenie dostępu do aparatu</string>
|
<string name="permission_camera_denied_body">Odmówiłeś dostępu do aparatu, lecz dodawanie kontaktów wymaga jego użycia.\n\nProszę rozważyć udzielenie dostępu do aparatu</string>
|
||||||
<string name="permission_location_denied_body">Zabroniłeś dostępu do Twojej lokalizacji, ale Briar potrzebuje tego uprawnienia do wykrywania urządzeń Bluetooth.\n\nRozważ przyznanie tego dostępu.</string>
|
<string name="permission_location_denied_body">Zabroniłeś dostępu do Twojej lokalizacji, ale Briar potrzebuje tego uprawnienia do wykrywania urządzeń Bluetooth.\n\nRozważ przyznanie tego dostępu.</string>
|
||||||
<string name="permission_location_setting_title">Ustawienia lokalizacji</string>
|
<string name="permission_location_setting_title">Ustawienia lokalizacji</string>
|
||||||
<string name="permission_location_setting_body">Ustawienie lokalizacji urządzenia musi być włączone, aby można było znaleźć inne urządzenia przez Bluetooth. Włącz lokalizację, aby kontynuować. Później możesz ją ponownie wyłączyć.</string>
|
<string name="permission_location_setting_body">Ustawienie lokalizacji urządzenia musi być włączone, aby można było znaleźć inne urządzenia przez Bluetooth. Włącz lokalizację, aby kontynuować. Później możesz ją ponownie wyłączyć.</string>
|
||||||
<string name="permission_location_setting_button">Włącz lokalizację</string>
|
<string name="permission_location_setting_button">Włącz lokalizację</string>
|
||||||
<string name="permission_bluetooth_title">Pozwolenie do urządzeń w pobliżu</string>
|
|
||||||
<string name="permission_bluetooth_body">Aby korzystać z komunikacji Bluetooth, Briar potrzebuje uprawnień do znajdowania i łączenia się z pobliskimi urządzeniami.</string>
|
|
||||||
<string name="permission_bluetooth_denied_body">Odmówiono dostępu do pobliskich urządzeń, ale Briar potrzebuje tego uprawnienia, aby korzystać z Bluetooth.\n\nRozważ udzielenie dostępu.</string>
|
|
||||||
<string name="qr_code">Kod QR</string>
|
<string name="qr_code">Kod QR</string>
|
||||||
<string name="show_qr_code_fullscreen">Pokaż QR na pełnym ekranie</string>
|
<string name="show_qr_code_fullscreen">Pokaż QR na pełnym ekranie</string>
|
||||||
<!--App Locking-->
|
<!--App Locking-->
|
||||||
|
|||||||
@@ -488,6 +488,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">Importar</string>
|
<string name="blogs_rss_feeds_import_button">Importar</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Entre a URL do feed RSS</string>
|
<string name="blogs_rss_feeds_import_hint">Entre a URL do feed RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Nós lamentamos! Houve um erro ao importar seu Feed.</string>
|
<string name="blogs_rss_feeds_import_error">Nós lamentamos! Houve um erro ao importar seu Feed.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Esse feed já foi importado.</string>
|
||||||
<string name="blogs_rss_feeds">Feeds RSS</string>
|
<string name="blogs_rss_feeds">Feeds RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importado:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importado:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
||||||
|
|||||||
@@ -446,10 +446,6 @@
|
|||||||
<string name="forum_declined_toast">Invitația a fost refuzată</string>
|
<string name="forum_declined_toast">Invitația a fost refuzată</string>
|
||||||
<string name="shared_by_format">Partajat de %s</string>
|
<string name="shared_by_format">Partajat de %s</string>
|
||||||
<string name="forum_invitation_already_sharing">Deja partajat</string>
|
<string name="forum_invitation_already_sharing">Deja partajat</string>
|
||||||
<string name="forum_invitation_already_invited">Invitație deja trimisă</string>
|
|
||||||
<string name="forum_invitation_invite_received">Invitație deja primită</string>
|
|
||||||
<string name="forum_invitation_not_supported">Nu este susținut de acest contact</string>
|
|
||||||
<string name="forum_invitation_error">Eroare. Aceasta este o eroare și nu este vina dumneavoastră</string>
|
|
||||||
<string name="forum_invitation_response_accepted_sent">Ați acceptat invitația la forum de la %s.</string>
|
<string name="forum_invitation_response_accepted_sent">Ați acceptat invitația la forum de la %s.</string>
|
||||||
<string name="forum_invitation_response_declined_sent">Ați refuzat invitația la forum de la %s.</string>
|
<string name="forum_invitation_response_declined_sent">Ați refuzat invitația la forum de la %s.</string>
|
||||||
<string name="forum_invitation_response_declined_auto">Invitația la forumu de la %s a fost refuzată automat.</string>
|
<string name="forum_invitation_response_declined_auto">Invitația la forumu de la %s a fost refuzată automat.</string>
|
||||||
@@ -501,9 +497,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">Importați flux RSS</string>
|
<string name="blogs_rss_feeds_import">Importați flux RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_button">Importați</string>
|
<string name="blogs_rss_feeds_import_button">Importați</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Introduceți adresa URL a fluxului RSS</string>
|
<string name="blogs_rss_feeds_import_hint">Introduceți adresa URL a fluxului RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">Importarea RSS Feed…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">Ne pare rău, dar a apărut o eroare la importarea fluxului dvs.</string>
|
<string name="blogs_rss_feeds_import_error">Ne pare rău, dar a apărut o eroare la importarea fluxului dvs.</string>
|
||||||
<string name="blogs_rss_feeds_import_title">Importați feed din fișier</string>
|
<string name="blogs_rss_feeds_import_exists">Fluxul respectiv este deja importat.</string>
|
||||||
<string name="blogs_rss_feeds">Fluxuri RSS</string>
|
<string name="blogs_rss_feeds">Fluxuri RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importat:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importat:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
||||||
|
|||||||
@@ -462,7 +462,7 @@
|
|||||||
<string name="forum_invitation_already_invited">Приглашение уже отправлено</string>
|
<string name="forum_invitation_already_invited">Приглашение уже отправлено</string>
|
||||||
<string name="forum_invitation_invite_received">Приглашение уже получено</string>
|
<string name="forum_invitation_invite_received">Приглашение уже получено</string>
|
||||||
<string name="forum_invitation_not_supported">Не поддерживается этим контактом</string>
|
<string name="forum_invitation_not_supported">Не поддерживается этим контактом</string>
|
||||||
<string name="forum_invitation_error">Это ошибка программы. Вы тут ни причем.</string>
|
<string name="forum_invitation_error">Ошибка. Это программная ошибка, а не ваша вина</string>
|
||||||
<string name="forum_invitation_response_accepted_sent">Вы приняли приглашение на форум от %s.</string>
|
<string name="forum_invitation_response_accepted_sent">Вы приняли приглашение на форум от %s.</string>
|
||||||
<string name="forum_invitation_response_declined_sent">Вы отклонили приглашение на форум от %s.</string>
|
<string name="forum_invitation_response_declined_sent">Вы отклонили приглашение на форум от %s.</string>
|
||||||
<string name="forum_invitation_response_declined_auto">Приглашение на форум от %s было отклонено автоматически.</string>
|
<string name="forum_invitation_response_declined_auto">Приглашение на форум от %s было отклонено автоматически.</string>
|
||||||
@@ -515,9 +515,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">Импорт RSS-ленты</string>
|
<string name="blogs_rss_feeds_import">Импорт RSS-ленты</string>
|
||||||
<string name="blogs_rss_feeds_import_button">Импорт</string>
|
<string name="blogs_rss_feeds_import_button">Импорт</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Введите URL-адрес RSS-ленты</string>
|
<string name="blogs_rss_feeds_import_hint">Введите URL-адрес RSS-ленты</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">Импорт RSS-лент...</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">Мы сожалеем! Произошла ошибка при импорте ленты.</string>
|
<string name="blogs_rss_feeds_import_error">Мы сожалеем! Произошла ошибка при импорте ленты.</string>
|
||||||
<string name="blogs_rss_feeds_import_title">Импорт ленты из файла</string>
|
<string name="blogs_rss_feeds_import_exists">Эта лента уже импортирована.</string>
|
||||||
<string name="blogs_rss_feeds">RSS-ленты</string>
|
<string name="blogs_rss_feeds">RSS-ленты</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Импортирован:</string>
|
<string name="blogs_rss_feeds_manage_imported">Импортирован:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Автор:</string>
|
<string name="blogs_rss_feeds_manage_author">Автор:</string>
|
||||||
|
|||||||
@@ -488,9 +488,8 @@ dhe s’mund të hapet me këtë version.\n\nJu lutemi, përmirësojeni me versi
|
|||||||
<string name="blogs_rss_feeds_import">Importoni Prurje RSS</string>
|
<string name="blogs_rss_feeds_import">Importoni Prurje RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_button">Importo</string>
|
<string name="blogs_rss_feeds_import_button">Importo</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Jepni URL-në e prurjes RSS</string>
|
<string name="blogs_rss_feeds_import_hint">Jepni URL-në e prurjes RSS</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">Po importohet Prurje RSS…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">Na ndjeni! Pati një gabim me importimin e prurjes tuaj.</string>
|
<string name="blogs_rss_feeds_import_error">Na ndjeni! Pati një gabim me importimin e prurjes tuaj.</string>
|
||||||
<string name="blogs_rss_feeds_import_title">Importo prurje nga kartelë</string>
|
<string name="blogs_rss_feeds_import_exists">Ajo prurje është importuar tashmë.</string>
|
||||||
<string name="blogs_rss_feeds">Prurje RSS</string>
|
<string name="blogs_rss_feeds">Prurje RSS</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Të importuara:</string>
|
<string name="blogs_rss_feeds_manage_imported">Të importuara:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
<string name="blogs_rss_feeds_manage_author">Autor:</string>
|
||||||
|
|||||||
@@ -478,6 +478,7 @@ Vänlige installera Briar på en nyare enhet.</string>
|
|||||||
<string name="blogs_rss_feeds_import_button">Importera</string>
|
<string name="blogs_rss_feeds_import_button">Importera</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Skriv URL till RSS-flödet</string>
|
<string name="blogs_rss_feeds_import_hint">Skriv URL till RSS-flödet</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Tyvärr! Något gick fel när flödet skulle importeras.</string>
|
<string name="blogs_rss_feeds_import_error">Tyvärr! Något gick fel när flödet skulle importeras.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Det flödet importeras redan.</string>
|
||||||
<string name="blogs_rss_feeds">RSS-flöden</string>
|
<string name="blogs_rss_feeds">RSS-flöden</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Importerade:</string>
|
<string name="blogs_rss_feeds_manage_imported">Importerade:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Författare:</string>
|
<string name="blogs_rss_feeds_manage_author">Författare:</string>
|
||||||
|
|||||||
@@ -482,6 +482,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">İçe Aktar</string>
|
<string name="blogs_rss_feeds_import_button">İçe Aktar</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">RSS beslemesi URL\'sini girin</string>
|
<string name="blogs_rss_feeds_import_hint">RSS beslemesi URL\'sini girin</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Üzgünüz! RSS beslemeniz içe aktarılırken bir hata oluştu.</string>
|
<string name="blogs_rss_feeds_import_error">Üzgünüz! RSS beslemeniz içe aktarılırken bir hata oluştu.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Bu besleme zaten içe aktarılmış.</string>
|
||||||
<string name="blogs_rss_feeds">RSS beslemeleri</string>
|
<string name="blogs_rss_feeds">RSS beslemeleri</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">İçe Aktarıldı:</string>
|
<string name="blogs_rss_feeds_manage_imported">İçe Aktarıldı:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Yazar:</string>
|
<string name="blogs_rss_feeds_manage_author">Yazar:</string>
|
||||||
@@ -593,7 +594,9 @@
|
|||||||
<string name="mailbox_setup_download_link">İndirme Bağlantısını Paylaş</string>
|
<string name="mailbox_setup_download_link">İndirme Bağlantısını Paylaş</string>
|
||||||
<string name="mailbox_setup_button_scan">Mailbox Karekodunu Tara</string>
|
<string name="mailbox_setup_button_scan">Mailbox Karekodunu Tara</string>
|
||||||
<string name="permission_camera_qr_denied_body">Kameraya erişimi engellediniz, ancak Mailbox karekodunu taramak için kamerayı kullanmanız gerekiyor.\n\nLütfen erişim izni vermeyi düşünün.</string>
|
<string name="permission_camera_qr_denied_body">Kameraya erişimi engellediniz, ancak Mailbox karekodunu taramak için kamerayı kullanmanız gerekiyor.\n\nLütfen erişim izni vermeyi düşünün.</string>
|
||||||
<!--This string is shown when connecting to a Mailbox for the first time. The placeholder will be replaced with a duration, e.g. "2 minutes".-->
|
<string name="mailbox_setup_connecting">Bağlantı kuruluyor…</string>
|
||||||
|
<string name="mailbox_setup_qr_code_wrong_title">Yanlış Karekod</string>
|
||||||
|
<string name="mailbox_setup_qr_code_wrong_description">Taranan kod geçersiz. Lütfen Briar Mailbox uygulamasını Mailbox aygıtınızda açın ve gösterdiği Karekodu tarayın.</string>
|
||||||
<string name="mailbox_setup_already_paired_title">Mailbox zaten bağlanmış</string>
|
<string name="mailbox_setup_already_paired_title">Mailbox zaten bağlanmış</string>
|
||||||
<string name="mailbox_setup_already_paired_description">Diğer aygıttan Mailbox bağlantısını kaldırın ve tekrar deneyin</string>
|
<string name="mailbox_setup_already_paired_description">Diğer aygıttan Mailbox bağlantısını kaldırın ve tekrar deneyin</string>
|
||||||
<string name="mailbox_setup_io_error_title">Bağlantı kurulamıyor</string>
|
<string name="mailbox_setup_io_error_title">Bağlantı kurulamıyor</string>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
<string name="dnkm_huawei_protected_text">Будь ласка, натисніть кнопку, що знаходиться нижче і впевніться у тому, що Briar захищено на екрані \"Захищені додатки\".</string>
|
<string name="dnkm_huawei_protected_text">Будь ласка, натисніть кнопку, що знаходиться нижче і впевніться у тому, що Briar захищено на екрані \"Захищені додатки\".</string>
|
||||||
<string name="dnkm_huawei_protected_button">Захистити Briar</string>
|
<string name="dnkm_huawei_protected_button">Захистити Briar</string>
|
||||||
<string name="dnkm_huawei_protected_help">Якщо Briar немає у списку захищених додатків, він не зможе працювати у фоновому режимі.</string>
|
<string name="dnkm_huawei_protected_help">Якщо Briar немає у списку захищених додатків, він не зможе працювати у фоновому режимі.</string>
|
||||||
<string name="dnkm_huawei_app_launch_text">Будь ласка, торкніться кнопки внизу, відкрийте екран «Запуск програми» й переконайтесь, що Briar має налаштування «Керувати вручну».</string>
|
<string name="dnkm_huawei_app_launch_text">Будь ласка, торкніть кнопку внизу, відкрийте екран «Запуск програми» й переконайтесь, що Briar має налаштування «Керувати вручну».</string>
|
||||||
<string name="dnkm_huawei_app_launch_help">Якщо не вказати «Керувати вручну» для Briar на екрані «Запуск програми», він не зможе працювати в фоновому режимі.</string>
|
<string name="dnkm_huawei_app_launch_help">Якщо не вказати «Керувати вручну» для Briar на екрані «Запуск програми», він не зможе працювати в фоновому режимі.</string>
|
||||||
<string name="dnkm_xiaomi_text">Щоб Briar працював у фоновому режимі, закріпіть його в переліку недавніх застосунків.</string>
|
<string name="dnkm_xiaomi_text">Щоб Briar працював у фоновому режимі, закріпіть його в переліку недавніх застосунків.</string>
|
||||||
<string name="dnkm_xiaomi_button">Захистити Briar</string>
|
<string name="dnkm_xiaomi_button">Захистити Briar</string>
|
||||||
@@ -505,6 +505,7 @@
|
|||||||
<string name="blogs_rss_feeds_import_button">Імпортувати</string>
|
<string name="blogs_rss_feeds_import_button">Імпортувати</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Введіть URL-посилання RSS-стрічки</string>
|
<string name="blogs_rss_feeds_import_hint">Введіть URL-посилання RSS-стрічки</string>
|
||||||
<string name="blogs_rss_feeds_import_error">Нам шкода! Виникла помилка під час імпорту вашої стрічки.</string>
|
<string name="blogs_rss_feeds_import_error">Нам шкода! Виникла помилка під час імпорту вашої стрічки.</string>
|
||||||
|
<string name="blogs_rss_feeds_import_exists">Цю стрічку вже імпортовано.</string>
|
||||||
<string name="blogs_rss_feeds">RSS-стрічки</string>
|
<string name="blogs_rss_feeds">RSS-стрічки</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Імпортовано:</string>
|
<string name="blogs_rss_feeds_manage_imported">Імпортовано:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Автор:</string>
|
<string name="blogs_rss_feeds_manage_author">Автор:</string>
|
||||||
@@ -515,7 +516,7 @@
|
|||||||
<string name="blogs_rss_feeds_manage_empty_state">Немає RSS-стрічок до відображення\n\nНатисніть на символ \"+\", щоб імпортувати стрічку</string>
|
<string name="blogs_rss_feeds_manage_empty_state">Немає RSS-стрічок до відображення\n\nНатисніть на символ \"+\", щоб імпортувати стрічку</string>
|
||||||
<string name="blogs_rss_feeds_manage_error">Під час завантаження ваших стрічок виникла проблема. Будь ласка, спробуйте пізніше.</string>
|
<string name="blogs_rss_feeds_manage_error">Під час завантаження ваших стрічок виникла проблема. Будь ласка, спробуйте пізніше.</string>
|
||||||
<!--Settings Profile Picture-->
|
<!--Settings Profile Picture-->
|
||||||
<string name="change_profile_picture">Торкніться, щоб змінити зображення профілю</string>
|
<string name="change_profile_picture">Торкніть, щоб змінити зображення профілю</string>
|
||||||
<string name="dialog_confirm_profile_picture_title">Змінити зображення профілю</string>
|
<string name="dialog_confirm_profile_picture_title">Змінити зображення профілю</string>
|
||||||
<string name="dialog_confirm_profile_picture_remark">Лише ваші контакти можуть бачити це зображення</string>
|
<string name="dialog_confirm_profile_picture_remark">Лише ваші контакти можуть бачити це зображення</string>
|
||||||
<string name="change_profile_picture_failed_message">Перепрошуємо, щось пішло не так при оновленні вашого зображення профілю</string>
|
<string name="change_profile_picture_failed_message">Перепрошуємо, щось пішло не так при оновленні вашого зображення профілю</string>
|
||||||
@@ -826,12 +827,12 @@
|
|||||||
<string name="removable_drive_explanation">Якщо не вдається з\'єднатися з контактом через інтернет, Wi-Fi та Bluetooth, Briar ще може передавати повідомлення за допомогою флешки чи SD-картки.\n\nКоли ви натиснете кнопку «Надіслати дані», будь-які дані в очікуванні надсилання контактові буде записано на флешку. Зокрема дані особистих повідомлень, прикріплень, блогів, форумів і приватних груп.\n\nПеред записом на флешку все буде зашифровано.\n\nОтримавши флешку, ваш контакт зможе імпортувати повідомлення в свій Briar кнопкою «Отримати дані».</string>
|
<string name="removable_drive_explanation">Якщо не вдається з\'єднатися з контактом через інтернет, Wi-Fi та Bluetooth, Briar ще може передавати повідомлення за допомогою флешки чи SD-картки.\n\nКоли ви натиснете кнопку «Надіслати дані», будь-які дані в очікуванні надсилання контактові буде записано на флешку. Зокрема дані особистих повідомлень, прикріплень, блогів, форумів і приватних груп.\n\nПеред записом на флешку все буде зашифровано.\n\nОтримавши флешку, ваш контакт зможе імпортувати повідомлення в свій Briar кнопкою «Отримати дані».</string>
|
||||||
<string name="removable_drive_title_send">Надіслати дані</string>
|
<string name="removable_drive_title_send">Надіслати дані</string>
|
||||||
<string name="removable_drive_title_receive">Отримати дані</string>
|
<string name="removable_drive_title_receive">Отримати дані</string>
|
||||||
<string name="removable_drive_send_intro">Торкніться кнопки внизу, щоб створити файл із зашифрованими повідомленнями. Ви зможете обрати, куди зберегти файл.\n\nЯкщо бажаєте зберегти файл на флешку, під\'єднайте її зараз.</string>
|
<string name="removable_drive_send_intro">Торкніть кнопку внизу, щоб створити файл зашифрованих повідомлень. Ви зможете обрати, куди зберегти файл.\n\nЯкщо бажаєте зберегти файл на флешку, під\'єднайте її зараз.</string>
|
||||||
<string name="removable_drive_send_no_data">Жодне повідомлення не очікує на надсилання цьому контактові.</string>
|
<string name="removable_drive_send_no_data">Жодне повідомлення не очікує на надсилання цьому контактові.</string>
|
||||||
<string name="removable_drive_send_not_supported">Контакт використовує стару версію Briar чи старий пристрій, що не підтримує цієї можливості.</string>
|
<string name="removable_drive_send_not_supported">Контакт використовує стару версію Briar чи старий пристрій, що не підтримує цієї можливості.</string>
|
||||||
<string name="removable_drive_send_button">Оберіть файл експорту</string>
|
<string name="removable_drive_send_button">Оберіть файл експорту</string>
|
||||||
<string name="removable_drive_ongoing">Дочекайтесь завершення поточного завдання</string>
|
<string name="removable_drive_ongoing">Дочекайтесь завершення поточного завдання</string>
|
||||||
<string name="removable_drive_receive_intro">Торкніться кнопки внизу, щоб обрати файл, надісланий вам контактом.\n\nЯкщо файл на флешці, під\'єднайте її зараз.</string>
|
<string name="removable_drive_receive_intro">Торкніть кнопку внизу, щоб обрати файл, надісланий вам контактом.\n\nЯкщо файл на флешці, під\'єднайте її зараз.</string>
|
||||||
<string name="removable_drive_receive_button">Оберіть файл імпорту</string>
|
<string name="removable_drive_receive_button">Оберіть файл імпорту</string>
|
||||||
<string name="removable_drive_success_send_title">Експорт успішний</string>
|
<string name="removable_drive_success_send_title">Експорт успішний</string>
|
||||||
<string name="removable_drive_success_send_text">Дані успішно експортовано. Маєте 28 днів, щоб передати файл контактові.\n\nЯкщо файл на флешці, перед від\'єднанням вимкніть її за допомогою сповіщення в рядку стану.</string>
|
<string name="removable_drive_success_send_text">Дані успішно експортовано. Маєте 28 днів, щоб передати файл контактові.\n\nЯкщо файл на флешці, перед від\'єднанням вимкніть її за допомогою сповіщення в рядку стану.</string>
|
||||||
|
|||||||
@@ -473,9 +473,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">导入 RSS 订阅源</string>
|
<string name="blogs_rss_feeds_import">导入 RSS 订阅源</string>
|
||||||
<string name="blogs_rss_feeds_import_button">导入</string>
|
<string name="blogs_rss_feeds_import_button">导入</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">输入 RSS 订阅源链接</string>
|
<string name="blogs_rss_feeds_import_hint">输入 RSS 订阅源链接</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">导入 RSS 订阅源中…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">抱歉!导入订阅源时发生错误。</string>
|
<string name="blogs_rss_feeds_import_error">抱歉!导入订阅源时发生错误。</string>
|
||||||
<string name="blogs_rss_feeds_import_title">从文件导入源</string>
|
<string name="blogs_rss_feeds_import_exists">已经导入那个源</string>
|
||||||
<string name="blogs_rss_feeds">RSS源 </string>
|
<string name="blogs_rss_feeds">RSS源 </string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">已导入:</string>
|
<string name="blogs_rss_feeds_manage_imported">已导入:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">作者:</string>
|
<string name="blogs_rss_feeds_manage_author">作者:</string>
|
||||||
|
|||||||
@@ -423,10 +423,6 @@
|
|||||||
<string name="forum_declined_toast">邀請已謝絕</string>
|
<string name="forum_declined_toast">邀請已謝絕</string>
|
||||||
<string name="shared_by_format">由 %s 分享</string>
|
<string name="shared_by_format">由 %s 分享</string>
|
||||||
<string name="forum_invitation_already_sharing">已在分享</string>
|
<string name="forum_invitation_already_sharing">已在分享</string>
|
||||||
<string name="forum_invitation_already_invited">已發送邀請</string>
|
|
||||||
<string name="forum_invitation_invite_received">已收到邀請</string>
|
|
||||||
<string name="forum_invitation_not_supported">此聯絡人無法使用</string>
|
|
||||||
<string name="forum_invitation_error">出錯,出了點問題與您無關</string>
|
|
||||||
<string name="forum_invitation_response_accepted_sent">您接受了來自 %s的論壇邀請</string>
|
<string name="forum_invitation_response_accepted_sent">您接受了來自 %s的論壇邀請</string>
|
||||||
<string name="forum_invitation_response_declined_sent">您謝絕了來自 %s的論壇邀請</string>
|
<string name="forum_invitation_response_declined_sent">您謝絕了來自 %s的論壇邀請</string>
|
||||||
<string name="forum_invitation_response_declined_auto">來自%s論壇的邀請已自動拒絕</string>
|
<string name="forum_invitation_response_declined_auto">來自%s論壇的邀請已自動拒絕</string>
|
||||||
@@ -476,9 +472,8 @@
|
|||||||
<string name="blogs_rss_feeds_import">導入 RSS 訂閱源</string>
|
<string name="blogs_rss_feeds_import">導入 RSS 訂閱源</string>
|
||||||
<string name="blogs_rss_feeds_import_button">導入</string>
|
<string name="blogs_rss_feeds_import_button">導入</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">輸入 RSS 訂閱源鏈接</string>
|
<string name="blogs_rss_feeds_import_hint">輸入 RSS 訂閱源鏈接</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">滙入 RSS 消息來源</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">抱歉!導入訂閱源時發生錯誤。</string>
|
<string name="blogs_rss_feeds_import_error">抱歉!導入訂閱源時發生錯誤。</string>
|
||||||
<string name="blogs_rss_feeds_import_title">透過檔案滙入消息源</string>
|
<string name="blogs_rss_feeds_import_exists">此來源已滙入</string>
|
||||||
<string name="blogs_rss_feeds">RSS 消息源</string>
|
<string name="blogs_rss_feeds">RSS 消息源</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">已導入:</string>
|
<string name="blogs_rss_feeds_manage_imported">已導入:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">作者:</string>
|
<string name="blogs_rss_feeds_manage_author">作者:</string>
|
||||||
|
|||||||
@@ -519,9 +519,7 @@
|
|||||||
<string name="blogs_rss_feeds_import">Import RSS Feed</string>
|
<string name="blogs_rss_feeds_import">Import RSS Feed</string>
|
||||||
<string name="blogs_rss_feeds_import_button">Import</string>
|
<string name="blogs_rss_feeds_import_button">Import</string>
|
||||||
<string name="blogs_rss_feeds_import_hint">Enter the URL of the RSS feed</string>
|
<string name="blogs_rss_feeds_import_hint">Enter the URL of the RSS feed</string>
|
||||||
<string name="blogs_rss_feeds_import_progress">Importing RSS Feed…</string>
|
|
||||||
<string name="blogs_rss_feeds_import_error">We are sorry! There was an error importing your feed.</string>
|
<string name="blogs_rss_feeds_import_error">We are sorry! There was an error importing your feed.</string>
|
||||||
<string name="blogs_rss_feeds_import_title">Import feed from file</string>
|
|
||||||
<string name="blogs_rss_feeds">RSS Feeds</string>
|
<string name="blogs_rss_feeds">RSS Feeds</string>
|
||||||
<string name="blogs_rss_feeds_manage_imported">Imported:</string>
|
<string name="blogs_rss_feeds_manage_imported">Imported:</string>
|
||||||
<string name="blogs_rss_feeds_manage_author">Author:</string>
|
<string name="blogs_rss_feeds_manage_author">Author:</string>
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ public class AttachmentReaderImpl implements AttachmentReader {
|
|||||||
String contentType = meta.getString(MSG_KEY_CONTENT_TYPE);
|
String contentType = meta.getString(MSG_KEY_CONTENT_TYPE);
|
||||||
if (!contentType.equals(h.getContentType()))
|
if (!contentType.equals(h.getContentType()))
|
||||||
throw new NoSuchMessageException();
|
throw new NoSuchMessageException();
|
||||||
int offset = meta.getInt(MSG_KEY_DESCRIPTOR_LENGTH);
|
int offset = meta.getLong(MSG_KEY_DESCRIPTOR_LENGTH).intValue();
|
||||||
InputStream stream = new ByteArrayInputStream(body, offset,
|
InputStream stream = new ByteArrayInputStream(body, offset,
|
||||||
body.length - offset);
|
body.length - offset);
|
||||||
return new Attachment(h, stream);
|
return new Attachment(h, stream);
|
||||||
|
|||||||
@@ -250,7 +250,7 @@ class AvatarManagerImpl implements AvatarManager, OpenDatabaseHook, ContactHook,
|
|||||||
try {
|
try {
|
||||||
BdfDictionary meta =
|
BdfDictionary meta =
|
||||||
clientHelper.getGroupMetadataAsDictionary(txn, g);
|
clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||||
return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID));
|
return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue());
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ class AvatarValidator implements MessageValidator {
|
|||||||
// 0.0: Message Type, Version, Content-Type
|
// 0.0: Message Type, Version, Content-Type
|
||||||
checkSize(body, 3);
|
checkSize(body, 3);
|
||||||
// Message Type
|
// Message Type
|
||||||
int messageType = body.getInt(0);
|
long messageType = body.getLong(0);
|
||||||
if (messageType != MSG_TYPE_UPDATE) throw new FormatException();
|
if (messageType != MSG_TYPE_UPDATE) throw new FormatException();
|
||||||
// Version
|
// Version
|
||||||
long version = body.getLong(1);
|
long version = body.getLong(1);
|
||||||
|
|||||||
@@ -487,7 +487,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private String getPostText(BdfList message) throws FormatException {
|
private String getPostText(BdfList message) throws FormatException {
|
||||||
MessageType type = MessageType.valueOf(message.getInt(0));
|
MessageType type = MessageType.valueOf(message.getLong(0).intValue());
|
||||||
if (type == POST) {
|
if (type == POST) {
|
||||||
// Type, text, signature
|
// Type, text, signature
|
||||||
return message.getString(1);
|
return message.getString(1);
|
||||||
@@ -621,6 +621,7 @@ class BlogManagerImpl extends BdfIncomingMessageHook implements BlogManager,
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MessageType getMessageType(BdfDictionary d) throws FormatException {
|
private MessageType getMessageType(BdfDictionary d) throws FormatException {
|
||||||
return MessageType.valueOf(d.getInt(KEY_TYPE));
|
Long longType = d.getLong(KEY_TYPE);
|
||||||
|
return MessageType.valueOf(longType.intValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -167,6 +167,6 @@ class BlogPostFactoryImpl implements BlogPostFactory {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private MessageType getType(BdfList body) throws FormatException {
|
private MessageType getType(BdfList body) throws FormatException {
|
||||||
return MessageType.valueOf(body.getInt(0));
|
return MessageType.valueOf(body.getLong(0).intValue());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class BlogPostValidator extends BdfMessageValidator {
|
|||||||
|
|
||||||
BdfMessageContext c;
|
BdfMessageContext c;
|
||||||
|
|
||||||
int type = body.getInt(0);
|
int type = body.getLong(0).intValue();
|
||||||
body.remove(0);
|
body.remove(0);
|
||||||
switch (MessageType.valueOf(type)) {
|
switch (MessageType.valueOf(type)) {
|
||||||
case POST:
|
case POST:
|
||||||
|
|||||||
@@ -114,8 +114,8 @@ class MessageTrackerImpl implements MessageTracker {
|
|||||||
try {
|
try {
|
||||||
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
|
BdfDictionary d = clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||||
return new GroupCount(
|
return new GroupCount(
|
||||||
d.getInt(GROUP_KEY_MSG_COUNT, 0),
|
d.getLong(GROUP_KEY_MSG_COUNT, 0L).intValue(),
|
||||||
d.getInt(GROUP_KEY_UNREAD_COUNT, 0),
|
d.getLong(GROUP_KEY_UNREAD_COUNT, 0L).intValue(),
|
||||||
d.getLong(GROUP_KEY_LATEST_MSG, 0L)
|
d.getLong(GROUP_KEY_LATEST_MSG, 0L)
|
||||||
);
|
);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ class IntroductionValidator extends BdfMessageValidator {
|
|||||||
@Override
|
@Override
|
||||||
protected BdfMessageContext validateMessage(Message m, Group g,
|
protected BdfMessageContext validateMessage(Message m, Group g,
|
||||||
BdfList body) throws FormatException {
|
BdfList body) throws FormatException {
|
||||||
MessageType type = MessageType.fromValue(body.getInt(0));
|
MessageType type = MessageType.fromValue(body.getLong(0).intValue());
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case REQUEST:
|
case REQUEST:
|
||||||
|
|||||||
@@ -59,8 +59,8 @@ class MessageParserImpl implements MessageParser {
|
|||||||
@Override
|
@Override
|
||||||
public MessageMetadata parseMetadata(BdfDictionary d)
|
public MessageMetadata parseMetadata(BdfDictionary d)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
MessageType type =
|
MessageType type = MessageType
|
||||||
MessageType.fromValue(d.getInt(MSG_KEY_MESSAGE_TYPE));
|
.fromValue(d.getLong(MSG_KEY_MESSAGE_TYPE).intValue());
|
||||||
byte[] sessionIdBytes = d.getOptionalRaw(MSG_KEY_SESSION_ID);
|
byte[] sessionIdBytes = d.getOptionalRaw(MSG_KEY_SESSION_ID);
|
||||||
SessionId sessionId =
|
SessionId sessionId =
|
||||||
sessionIdBytes == null ? null : new SessionId(sessionIdBytes);
|
sessionIdBytes == null ? null : new SessionId(sessionIdBytes);
|
||||||
|
|||||||
@@ -72,7 +72,7 @@ class SessionParserImpl implements SessionParser {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Role getRole(BdfDictionary d) throws FormatException {
|
public Role getRole(BdfDictionary d) throws FormatException {
|
||||||
return Role.fromValue(d.getInt(SESSION_KEY_ROLE));
|
return Role.fromValue(d.getLong(SESSION_KEY_ROLE).intValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -97,7 +97,7 @@ class SessionParserImpl implements SessionParser {
|
|||||||
MessageId lastRemoteMessageId =
|
MessageId lastRemoteMessageId =
|
||||||
getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID);
|
getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID);
|
||||||
long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
||||||
GroupId groupId = getGroupId(d);
|
GroupId groupId = getGroupId(d, SESSION_KEY_GROUP_ID);
|
||||||
Author author = getAuthor(d, SESSION_KEY_AUTHOR);
|
Author author = getAuthor(d, SESSION_KEY_AUTHOR);
|
||||||
return new Introducee(sessionId, groupId, author, localTimestamp,
|
return new Introducee(sessionId, groupId, author, localTimestamp,
|
||||||
lastLocalMessageId, lastRemoteMessageId);
|
lastLocalMessageId, lastRemoteMessageId);
|
||||||
@@ -126,10 +126,12 @@ class SessionParserImpl implements SessionParser {
|
|||||||
MessageId lastLocalMessageId =
|
MessageId lastLocalMessageId =
|
||||||
getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID);
|
getMessageId(d, SESSION_KEY_LAST_LOCAL_MESSAGE_ID);
|
||||||
long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
long localTimestamp = d.getLong(SESSION_KEY_LOCAL_TIMESTAMP);
|
||||||
PublicKey ephemeralPublicKey = getEphemeralPublicKey(d);
|
PublicKey ephemeralPublicKey =
|
||||||
|
getEphemeralPublicKey(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
|
||||||
BdfDictionary tpDict =
|
BdfDictionary tpDict =
|
||||||
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
|
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
|
||||||
PrivateKey ephemeralPrivateKey = getEphemeralPrivateKey(d);
|
PrivateKey ephemeralPrivateKey =
|
||||||
|
getEphemeralPrivateKey(d, SESSION_KEY_EPHEMERAL_PRIVATE_KEY);
|
||||||
Map<TransportId, TransportProperties> transportProperties =
|
Map<TransportId, TransportProperties> transportProperties =
|
||||||
tpDict == null ? null : clientHelper
|
tpDict == null ? null : clientHelper
|
||||||
.parseAndValidateTransportPropertiesMap(tpDict);
|
.parseAndValidateTransportPropertiesMap(tpDict);
|
||||||
@@ -145,7 +147,8 @@ class SessionParserImpl implements SessionParser {
|
|||||||
Author remoteAuthor = getAuthor(d, SESSION_KEY_REMOTE_AUTHOR);
|
Author remoteAuthor = getAuthor(d, SESSION_KEY_REMOTE_AUTHOR);
|
||||||
MessageId lastRemoteMessageId =
|
MessageId lastRemoteMessageId =
|
||||||
getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID);
|
getMessageId(d, SESSION_KEY_LAST_REMOTE_MESSAGE_ID);
|
||||||
PublicKey ephemeralPublicKey = getEphemeralPublicKey(d);
|
PublicKey ephemeralPublicKey =
|
||||||
|
getEphemeralPublicKey(d, SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
|
||||||
BdfDictionary tpDict =
|
BdfDictionary tpDict =
|
||||||
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
|
d.getOptionalDictionary(SESSION_KEY_TRANSPORT_PROPERTIES);
|
||||||
Map<TransportId, TransportProperties> transportProperties =
|
Map<TransportId, TransportProperties> transportProperties =
|
||||||
@@ -159,7 +162,7 @@ class SessionParserImpl implements SessionParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private int getState(BdfDictionary d) throws FormatException {
|
private int getState(BdfDictionary d) throws FormatException {
|
||||||
return d.getInt(SESSION_KEY_STATE);
|
return d.getLong(SESSION_KEY_STATE).intValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private SessionId getSessionId(BdfDictionary d) throws FormatException {
|
private SessionId getSessionId(BdfDictionary d) throws FormatException {
|
||||||
@@ -174,8 +177,9 @@ class SessionParserImpl implements SessionParser {
|
|||||||
return b == null ? null : new MessageId(b);
|
return b == null ? null : new MessageId(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
private GroupId getGroupId(BdfDictionary d) throws FormatException {
|
private GroupId getGroupId(BdfDictionary d, String key)
|
||||||
return new GroupId(d.getRaw(SESSION_KEY_GROUP_ID));
|
throws FormatException {
|
||||||
|
return new GroupId(d.getRaw(key));
|
||||||
}
|
}
|
||||||
|
|
||||||
private Author getAuthor(BdfDictionary d, String key)
|
private Author getAuthor(BdfDictionary d, String key)
|
||||||
@@ -189,22 +193,23 @@ class SessionParserImpl implements SessionParser {
|
|||||||
if (d == null) return null;
|
if (d == null) return null;
|
||||||
Map<TransportId, KeySetId> map = new HashMap<>(d.size());
|
Map<TransportId, KeySetId> map = new HashMap<>(d.size());
|
||||||
for (String key : d.keySet()) {
|
for (String key : d.keySet()) {
|
||||||
map.put(new TransportId(key), new KeySetId(d.getInt(key)));
|
map.put(new TransportId(key),
|
||||||
|
new KeySetId(d.getLong(key).intValue()));
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private PublicKey getEphemeralPublicKey(BdfDictionary d)
|
private PublicKey getEphemeralPublicKey(BdfDictionary d, String key)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
byte[] keyBytes = d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PUBLIC_KEY);
|
byte[] keyBytes = d.getOptionalRaw(key);
|
||||||
return keyBytes == null ? null : new AgreementPublicKey(keyBytes);
|
return keyBytes == null ? null : new AgreementPublicKey(keyBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private PrivateKey getEphemeralPrivateKey(BdfDictionary d)
|
private PrivateKey getEphemeralPrivateKey(BdfDictionary d, String key)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
byte[] keyBytes = d.getOptionalRaw(SESSION_KEY_EPHEMERAL_PRIVATE_KEY);
|
byte[] keyBytes = d.getOptionalRaw(key);
|
||||||
return keyBytes == null ? null : new AgreementPrivateKey(keyBytes);
|
return keyBytes == null ? null : new AgreementPrivateKey(keyBytes);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -182,7 +182,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
try {
|
try {
|
||||||
BdfDictionary metaDict = metadataParser.parse(meta);
|
BdfDictionary metaDict = metadataParser.parse(meta);
|
||||||
// Message type is null for version 0.0 private messages
|
// Message type is null for version 0.0 private messages
|
||||||
Integer messageType = metaDict.getOptionalInt(MSG_KEY_MSG_TYPE);
|
Long messageType = metaDict.getOptionalLong(MSG_KEY_MSG_TYPE);
|
||||||
if (messageType == null) {
|
if (messageType == null) {
|
||||||
incomingPrivateMessage(txn, m, metaDict, true, emptyList());
|
incomingPrivateMessage(txn, m, metaDict, true, emptyList());
|
||||||
} else if (messageType == PRIVATE_MESSAGE) {
|
} else if (messageType == PRIVATE_MESSAGE) {
|
||||||
@@ -371,7 +371,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
try {
|
try {
|
||||||
BdfDictionary meta =
|
BdfDictionary meta =
|
||||||
clientHelper.getGroupMetadataAsDictionary(txn, g);
|
clientHelper.getGroupMetadataAsDictionary(txn, g);
|
||||||
return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID));
|
return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue());
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -381,7 +381,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
public ContactId getContactId(GroupId g) throws DbException {
|
public ContactId getContactId(GroupId g) throws DbException {
|
||||||
try {
|
try {
|
||||||
BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(g);
|
BdfDictionary meta = clientHelper.getGroupMetadataAsDictionary(g);
|
||||||
return new ContactId(meta.getInt(GROUP_KEY_CONTACT_ID));
|
return new ContactId(meta.getLong(GROUP_KEY_CONTACT_ID).intValue());
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
}
|
}
|
||||||
@@ -419,7 +419,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
if (meta == null) continue;
|
if (meta == null) continue;
|
||||||
try {
|
try {
|
||||||
// Message type is null for version 0.0 private messages
|
// Message type is null for version 0.0 private messages
|
||||||
Integer messageType = meta.getOptionalInt(MSG_KEY_MSG_TYPE);
|
Long messageType = meta.getOptionalLong(MSG_KEY_MSG_TYPE);
|
||||||
if (messageType != null && messageType != PRIVATE_MESSAGE)
|
if (messageType != null && messageType != PRIVATE_MESSAGE)
|
||||||
continue;
|
continue;
|
||||||
long timestamp = meta.getLong(MSG_KEY_TIMESTAMP);
|
long timestamp = meta.getLong(MSG_KEY_TIMESTAMP);
|
||||||
@@ -453,8 +453,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
Map<MessageId, BdfDictionary> messages =
|
Map<MessageId, BdfDictionary> messages =
|
||||||
clientHelper.getMessageMetadataAsDictionary(txn, g);
|
clientHelper.getMessageMetadataAsDictionary(txn, g);
|
||||||
for (Entry<MessageId, BdfDictionary> entry : messages.entrySet()) {
|
for (Entry<MessageId, BdfDictionary> entry : messages.entrySet()) {
|
||||||
Integer type =
|
Long type = entry.getValue().getOptionalLong(MSG_KEY_MSG_TYPE);
|
||||||
entry.getValue().getOptionalInt(MSG_KEY_MSG_TYPE);
|
|
||||||
if (type == null || type == PRIVATE_MESSAGE)
|
if (type == null || type == PRIVATE_MESSAGE)
|
||||||
result.add(entry.getKey());
|
result.add(entry.getKey());
|
||||||
}
|
}
|
||||||
@@ -528,7 +527,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
try {
|
try {
|
||||||
BdfDictionary meta =
|
BdfDictionary meta =
|
||||||
clientHelper.getMessageMetadataAsDictionary(txn, m);
|
clientHelper.getMessageMetadataAsDictionary(txn, m);
|
||||||
Integer messageType = meta.getOptionalInt(MSG_KEY_MSG_TYPE);
|
Long messageType = meta.getOptionalLong(MSG_KEY_MSG_TYPE);
|
||||||
if (messageType != null && messageType == PRIVATE_MESSAGE) {
|
if (messageType != null && messageType == PRIVATE_MESSAGE) {
|
||||||
for (AttachmentHeader h : parseAttachmentHeaders(g, meta)) {
|
for (AttachmentHeader h : parseAttachmentHeaders(g, meta)) {
|
||||||
try {
|
try {
|
||||||
@@ -555,7 +554,7 @@ class MessagingManagerImpl implements MessagingManager, IncomingMessageHook,
|
|||||||
int unreadCount = 0;
|
int unreadCount = 0;
|
||||||
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
||||||
BdfDictionary meta = entry.getValue();
|
BdfDictionary meta = entry.getValue();
|
||||||
Integer messageType = meta.getOptionalInt(MSG_KEY_MSG_TYPE);
|
Long messageType = meta.getOptionalLong(MSG_KEY_MSG_TYPE);
|
||||||
if (messageType == null || messageType == PRIVATE_MESSAGE) {
|
if (messageType == null || messageType == PRIVATE_MESSAGE) {
|
||||||
msgCount++;
|
msgCount++;
|
||||||
if (!meta.getBoolean(MSG_KEY_READ)) unreadCount++;
|
if (!meta.getBoolean(MSG_KEY_READ)) unreadCount++;
|
||||||
|
|||||||
@@ -84,7 +84,7 @@ class PrivateMessageValidator implements MessageValidator {
|
|||||||
context = validateLegacyPrivateMessage(m, list);
|
context = validateLegacyPrivateMessage(m, list);
|
||||||
} else {
|
} else {
|
||||||
// Private message or attachment
|
// Private message or attachment
|
||||||
int messageType = list.getInt(0);
|
int messageType = list.getLong(0).intValue();
|
||||||
if (messageType == PRIVATE_MESSAGE) {
|
if (messageType == PRIVATE_MESSAGE) {
|
||||||
if (!reader.eof()) throw new FormatException();
|
if (!reader.eof()) throw new FormatException();
|
||||||
context = validatePrivateMessage(m, list);
|
context = validatePrivateMessage(m, list);
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ class GroupMessageValidator extends BdfMessageValidator {
|
|||||||
checkSize(body, 4, 6);
|
checkSize(body, 4, 6);
|
||||||
|
|
||||||
// Message type (int)
|
// Message type (int)
|
||||||
int type = body.getInt(0);
|
int type = body.getLong(0).intValue();
|
||||||
|
|
||||||
// Member (author)
|
// Member (author)
|
||||||
BdfList memberList = body.getList(1);
|
BdfList memberList = body.getList(1);
|
||||||
|
|||||||
@@ -366,7 +366,7 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
// parse the metadata
|
// parse the metadata
|
||||||
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
||||||
BdfDictionary meta = entry.getValue();
|
BdfDictionary meta = entry.getValue();
|
||||||
if (meta.getInt(KEY_TYPE) == JOIN.getInt()) {
|
if (meta.getLong(KEY_TYPE) == JOIN.getInt()) {
|
||||||
headers.add(getJoinMessageHeader(txn, g, entry.getKey(),
|
headers.add(getJoinMessageHeader(txn, g, entry.getKey(),
|
||||||
meta, authorInfos));
|
meta, authorInfos));
|
||||||
} else {
|
} else {
|
||||||
@@ -530,7 +530,8 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
BdfList body, BdfDictionary meta)
|
BdfList body, BdfDictionary meta)
|
||||||
throws DbException, FormatException {
|
throws DbException, FormatException {
|
||||||
|
|
||||||
MessageType type = MessageType.valueOf(meta.getInt(KEY_TYPE));
|
MessageType type =
|
||||||
|
MessageType.valueOf(meta.getLong(KEY_TYPE).intValue());
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case JOIN:
|
case JOIN:
|
||||||
handleJoinMessage(txn, m, meta);
|
handleJoinMessage(txn, m, meta);
|
||||||
@@ -575,8 +576,8 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
.getMessageMetadataAsDictionary(txn, parentId);
|
.getMessageMetadataAsDictionary(txn, parentId);
|
||||||
if (timestamp <= parentMeta.getLong(KEY_TIMESTAMP))
|
if (timestamp <= parentMeta.getLong(KEY_TIMESTAMP))
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
MessageType parentType =
|
MessageType parentType = MessageType
|
||||||
MessageType.valueOf(parentMeta.getInt(KEY_TYPE));
|
.valueOf(parentMeta.getLong(KEY_TYPE).intValue());
|
||||||
if (parentType != POST)
|
if (parentType != POST)
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
}
|
}
|
||||||
@@ -591,8 +592,8 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
if (!getAuthor(meta).equals(getAuthor(previousMeta)))
|
if (!getAuthor(meta).equals(getAuthor(previousMeta)))
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
// previous message must be a POST or JOIN
|
// previous message must be a POST or JOIN
|
||||||
MessageType previousType =
|
MessageType previousType = MessageType
|
||||||
MessageType.valueOf(previousMeta.getInt(KEY_TYPE));
|
.valueOf(previousMeta.getLong(KEY_TYPE).intValue());
|
||||||
if (previousType != JOIN && previousType != POST)
|
if (previousType != JOIN && previousType != POST)
|
||||||
throw new FormatException();
|
throw new FormatException();
|
||||||
// track message and broadcast event
|
// track message and broadcast event
|
||||||
@@ -640,7 +641,8 @@ class PrivateGroupManagerImpl extends BdfIncomingMessageHook
|
|||||||
|
|
||||||
private Visibility getVisibility(BdfDictionary meta)
|
private Visibility getVisibility(BdfDictionary meta)
|
||||||
throws FormatException {
|
throws FormatException {
|
||||||
return Visibility.valueOf(meta.getInt(GROUP_KEY_VISIBILITY));
|
return Visibility
|
||||||
|
.valueOf(meta.getLong(GROUP_KEY_VISIBILITY).intValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,12 @@ package org.briarproject.briar.privategroup.invitation;
|
|||||||
|
|
||||||
interface GroupInvitationConstants {
|
interface GroupInvitationConstants {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Metadata key for the client's local group, indicating that contact
|
||||||
|
* groups have been created for all contacts.
|
||||||
|
*/
|
||||||
|
String GROUP_KEY_SETUP = "setup";
|
||||||
|
|
||||||
// Message metadata keys
|
// Message metadata keys
|
||||||
String MSG_KEY_MESSAGE_TYPE = "messageType";
|
String MSG_KEY_MESSAGE_TYPE = "messageType";
|
||||||
String MSG_KEY_PRIVATE_GROUP_ID = "privateGroupId";
|
String MSG_KEY_PRIVATE_GROUP_ID = "privateGroupId";
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import org.briarproject.bramble.api.contact.Contact;
|
|||||||
import org.briarproject.bramble.api.contact.ContactId;
|
import org.briarproject.bramble.api.contact.ContactId;
|
||||||
import org.briarproject.bramble.api.contact.ContactManager.ContactHook;
|
import org.briarproject.bramble.api.contact.ContactManager.ContactHook;
|
||||||
import org.briarproject.bramble.api.data.BdfDictionary;
|
import org.briarproject.bramble.api.data.BdfDictionary;
|
||||||
|
import org.briarproject.bramble.api.data.BdfEntry;
|
||||||
import org.briarproject.bramble.api.data.BdfList;
|
import org.briarproject.bramble.api.data.BdfList;
|
||||||
import org.briarproject.bramble.api.data.MetadataParser;
|
import org.briarproject.bramble.api.data.MetadataParser;
|
||||||
import org.briarproject.bramble.api.db.DatabaseComponent;
|
import org.briarproject.bramble.api.db.DatabaseComponent;
|
||||||
@@ -63,6 +64,7 @@ import static org.briarproject.briar.privategroup.invitation.CreatorState.ERROR;
|
|||||||
import static org.briarproject.briar.privategroup.invitation.CreatorState.INVITED;
|
import static org.briarproject.briar.privategroup.invitation.CreatorState.INVITED;
|
||||||
import static org.briarproject.briar.privategroup.invitation.CreatorState.JOINED;
|
import static org.briarproject.briar.privategroup.invitation.CreatorState.JOINED;
|
||||||
import static org.briarproject.briar.privategroup.invitation.CreatorState.START;
|
import static org.briarproject.briar.privategroup.invitation.CreatorState.START;
|
||||||
|
import static org.briarproject.briar.privategroup.invitation.GroupInvitationConstants.GROUP_KEY_SETUP;
|
||||||
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
|
import static org.briarproject.briar.privategroup.invitation.MessageType.ABORT;
|
||||||
import static org.briarproject.briar.privategroup.invitation.MessageType.INVITE;
|
import static org.briarproject.briar.privategroup.invitation.MessageType.INVITE;
|
||||||
import static org.briarproject.briar.privategroup.invitation.MessageType.JOIN;
|
import static org.briarproject.briar.privategroup.invitation.MessageType.JOIN;
|
||||||
@@ -114,13 +116,35 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDatabaseOpened(Transaction txn) throws DbException {
|
public void onDatabaseOpened(Transaction txn) throws DbException {
|
||||||
// Create a local group to indicate that we've set this client up
|
// If the feature flag for this client was set and then cleared, we may
|
||||||
|
// have set things up for some pre-existing contacts and not others.
|
||||||
|
// If the local group exists and has GROUP_KEY_SETUP == true in its
|
||||||
|
// metadata then we've set things up for all contacts. Otherwise we
|
||||||
|
// need to check whether a contact group exists for each contact.
|
||||||
Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
|
Group localGroup = contactGroupFactory.createLocalGroup(CLIENT_ID,
|
||||||
MAJOR_VERSION);
|
MAJOR_VERSION);
|
||||||
if (db.containsGroup(txn, localGroup.getId())) return;
|
try {
|
||||||
db.addGroup(txn, localGroup);
|
if (db.containsGroup(txn, localGroup.getId())) {
|
||||||
// Set things up for any pre-existing contacts
|
// If GROUP_KEY_SETUP == true then we're done
|
||||||
for (Contact c : db.getContacts(txn)) addingContact(txn, c);
|
BdfDictionary meta = clientHelper
|
||||||
|
.getGroupMetadataAsDictionary(txn, localGroup.getId());
|
||||||
|
if (meta.getBoolean(GROUP_KEY_SETUP, false)) return;
|
||||||
|
} else {
|
||||||
|
db.addGroup(txn, localGroup);
|
||||||
|
}
|
||||||
|
BdfDictionary meta =
|
||||||
|
BdfDictionary.of(new BdfEntry(GROUP_KEY_SETUP, true));
|
||||||
|
clientHelper.mergeGroupMetadata(txn, localGroup.getId(), meta);
|
||||||
|
} catch (FormatException e) {
|
||||||
|
throw new DbException(e);
|
||||||
|
}
|
||||||
|
// Set things up for any contacts that haven't already been set up
|
||||||
|
for (Contact c : db.getContacts(txn)) {
|
||||||
|
Group contactGroup = getContactGroup(c);
|
||||||
|
if (!db.containsGroup(txn, contactGroup.getId())) {
|
||||||
|
addingContact(txn, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -712,9 +736,9 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
// get all sessions and their states
|
// get all sessions and their states
|
||||||
Map<GroupId, DeletableSession> sessions = new HashMap<>();
|
Map<GroupId, DeletableSession> sessions = new HashMap<>();
|
||||||
for (BdfDictionary d : metadata.values()) {
|
for (BdfDictionary d : metadata.values()) {
|
||||||
|
if (!sessionParser.isSession(d)) continue;
|
||||||
Session<?> session;
|
Session<?> session;
|
||||||
try {
|
try {
|
||||||
if (!sessionParser.isSession(d)) continue;
|
|
||||||
session = sessionParser.parseSession(g, d);
|
session = sessionParser.parseSession(g, d);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
@@ -776,12 +800,13 @@ class GroupInvitationManagerImpl extends ConversationClientImpl
|
|||||||
|
|
||||||
// assign protocol messages to their sessions
|
// assign protocol messages to their sessions
|
||||||
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
for (Entry<MessageId, BdfDictionary> entry : metadata.entrySet()) {
|
||||||
|
// skip all sessions, we are only interested in messages
|
||||||
|
BdfDictionary d = entry.getValue();
|
||||||
|
if (sessionParser.isSession(d)) continue;
|
||||||
|
|
||||||
// parse message metadata and skip messages not visible in UI
|
// parse message metadata and skip messages not visible in UI
|
||||||
MessageMetadata m;
|
MessageMetadata m;
|
||||||
try {
|
try {
|
||||||
// skip all sessions, we are only interested in messages
|
|
||||||
BdfDictionary d = entry.getValue();
|
|
||||||
if (sessionParser.isSession(d)) continue;
|
|
||||||
m = messageParser.parseMetadata(d);
|
m = messageParser.parseMetadata(d);
|
||||||
} catch (FormatException e) {
|
} catch (FormatException e) {
|
||||||
throw new DbException(e);
|
throw new DbException(e);
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class GroupInvitationValidator extends BdfMessageValidator {
|
|||||||
@Override
|
@Override
|
||||||
protected BdfMessageContext validateMessage(Message m, Group g,
|
protected BdfMessageContext validateMessage(Message m, Group g,
|
||||||
BdfList body) throws FormatException {
|
BdfList body) throws FormatException {
|
||||||
MessageType type = MessageType.fromValue(body.getInt(0));
|
MessageType type = MessageType.fromValue(body.getLong(0).intValue());
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case INVITE:
|
case INVITE:
|
||||||
return validateInviteMessage(m, body);
|
return validateInviteMessage(m, body);
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user