Fix up PacketLoader.

Add non-cache support for Base64Packet.
This commit is contained in:
Captain ALM 2023-05-21 13:37:54 +01:00
parent 02f34c02ec
commit f873983ffa
Signed by: alfred
GPG Key ID: 4E4ADD02609997B1
2 changed files with 123 additions and 18 deletions

View File

@ -269,7 +269,7 @@ public class PacketLoader {
} }
/** /**
* Writes a {@link IPacket} to an output stream. * Writes a {@link IPacket} to an output stream (No digest support).
* *
* @param outputStream The output stream for writing. * @param outputStream The output stream for writing.
* @param packet The packet to save. * @param packet The packet to save.
@ -299,6 +299,35 @@ public class PacketLoader {
outputStream.flush(); outputStream.flush();
} }
/**
* Writes a {@link IPacket} to an output stream.
* NOTE: The {@link #getHashProvider()} for digests is NOT supported and no digest is expected for these packets.
*
* @param outputStream The output stream for writing.
* @param packet The packet to save.
* @param writeInformation Write the {@link PacketProtocolInformation} to the stream.
* @throws NullPointerException A parameter is null.
* @throws IOException A stream exception occurs.
* @throws PacketException An Exception has occurred.
*/
public void writePacketNoDigest(OutputStream outputStream, IPacket packet, boolean writeInformation) throws IOException, PacketException {
if (outputStream == null) throw new NullPointerException("outputStream is null");
if (packet == null) throw new NullPointerException("packet is null");
if (isPacketInvalid(packet)) throw new PacketException("packet is invalid");
if (writeInformation) savePacketProtocolInformation(outputStream, packet.getProtocol());
if (packet instanceof IStreamedPacket) {
writeInteger(outputStream, ((IStreamedPacket) packet).getSize());
((IStreamedPacket) packet).readData(outputStream);
} else {
byte[] saveArray = packet.savePayload();
writeInteger(outputStream, saveArray.length);
outputStream.write(saveArray);
}
outputStream.flush();
}
/** /**
* Reads an Integer from an {@link InputStream}. * Reads an Integer from an {@link InputStream}.
* *
@ -411,13 +440,14 @@ public class PacketLoader {
* *
* @param packet The packet to check. * @param packet The packet to check.
* @param includeInformation If the 2 byte information header is included. * @param includeInformation If the 2 byte information header is included.
* @param ignoreDigest If the digest length should be ignored if available.
* @return The size of the packet in bytes. * @return The size of the packet in bytes.
* @throws NullPointerException packet is null. * @throws NullPointerException packet is null.
* @throws PacketException A Packet Exception has occurred. * @throws PacketException A Packet Exception has occurred.
*/ */
public int getPacketSize(IPacket packet, boolean includeInformation) throws PacketException { public int getPacketSize(IPacket packet, boolean includeInformation, boolean ignoreDigest) throws PacketException {
if (packet == null) throw new NullPointerException("packet is null"); if (packet == null) throw new NullPointerException("packet is null");
return ((includeInformation) ? 2 : 0) + ((packet instanceof IStreamedPacket) ? ((IStreamedPacket) packet).getSize() : packet.savePayload().length) return 4 + ((includeInformation) ? 2 : 0) + ((packet instanceof IStreamedPacket) ? ((IStreamedPacket) packet).getSize() : packet.savePayload().length)
+ ((hashProvider == null) ? 0 : hashProvider.getLength()); + ((ignoreDigest || hashProvider == null) ? 0 : hashProvider.getLength());
} }
} }

View File

@ -26,6 +26,7 @@ public class Base64Packet implements IStreamedPacket {
protected IPacketFactory factory; protected IPacketFactory factory;
protected IPacket held; protected IPacket held;
protected byte[] encryptedCache; protected byte[] encryptedCache;
protected boolean useCache;
/** /**
* Constructs a new Base64Packet with the specified {@link IPacketFactory} and {@link PacketLoader}. * Constructs a new Base64Packet with the specified {@link IPacketFactory} and {@link PacketLoader}.
@ -35,7 +36,20 @@ public class Base64Packet implements IStreamedPacket {
* @throws NullPointerException factory or loader is null. * @throws NullPointerException factory or loader is null.
*/ */
public Base64Packet(IPacketFactory factory, PacketLoader loader) { public Base64Packet(IPacketFactory factory, PacketLoader loader) {
this(factory, loader, null); this(factory, loader, false);
}
/**
* Constructs a new Base64Packet with the specified {@link IPacketFactory}, {@link PacketLoader}
* and if the encrypted data should be cached.
*
* @param factory The packet factory to use.
* @param loader The Packet Loader to use.
* @param useCache If the encrypted data should be cached.
* @throws NullPointerException factory or loader is null.
*/
public Base64Packet(IPacketFactory factory, PacketLoader loader, boolean useCache) {
this(factory, loader, null, useCache);
} }
/** /**
@ -47,11 +61,26 @@ public class Base64Packet implements IStreamedPacket {
* @throws NullPointerException factory or loader is null. * @throws NullPointerException factory or loader is null.
*/ */
public Base64Packet(IPacketFactory factory, PacketLoader loader, IPacket packet) { public Base64Packet(IPacketFactory factory, PacketLoader loader, IPacket packet) {
this(factory, loader, packet, false);
}
/**
* Constructs a new Base64Packet with the specified {@link IPacketFactory}, {@link PacketLoader},
* {@link IPacket} and if the encrypted data should be cached.
*
* @param factory The packet factory to use.
* @param loader The Packet Loader to use.
* @param packet The packet to store or null.
* @param useCache If the encrypted data should be cached.
* @throws NullPointerException factory or loader is null.
*/
public Base64Packet(IPacketFactory factory, PacketLoader loader, IPacket packet, boolean useCache) {
if (factory == null) throw new NullPointerException("factory is null"); if (factory == null) throw new NullPointerException("factory is null");
if (loader == null) throw new NullPointerException("loader is null"); if (loader == null) throw new NullPointerException("loader is null");
this.factory = factory; this.factory = factory;
held = packet; held = packet;
this.loader = loader; this.loader = loader;
this.useCache = useCache;
} }
/** /**
@ -99,8 +128,13 @@ public class Base64Packet implements IStreamedPacket {
@Override @Override
public byte[] savePayload() throws PacketException { public byte[] savePayload() throws PacketException {
synchronized (slock) { synchronized (slock) {
processEncryptedCache(); if (useCache) {
return encryptedCache; processEncryptedCache();
return encryptedCache;
} else {
if (held == null) throw new PacketException("no data");
return Base64.getEncoder().encode(loader.writePacketNoDigest(held, true));
}
} }
} }
@ -115,13 +149,22 @@ public class Base64Packet implements IStreamedPacket {
public void loadPayload(byte[] packetData) throws PacketException { public void loadPayload(byte[] packetData) throws PacketException {
if (packetData == null) throw new NullPointerException("packetData is null"); if (packetData == null) throw new NullPointerException("packetData is null");
synchronized (slock) { synchronized (slock) {
encryptedCache = packetData; if (useCache) {
try { encryptedCache = packetData;
byte[] payload = Base64.getDecoder().decode(encryptedCache); try {
held = loader.readPacketNoDigest(payload, factory, null); byte[] payload = Base64.getDecoder().decode(encryptedCache);
} catch (IllegalArgumentException e) { held = loader.readPacketNoDigest(payload, factory, null);
encryptedCache = null; } catch (IllegalArgumentException e) {
throw new PacketException(e); encryptedCache = null;
throw new PacketException(e);
}
} else {
try {
byte[] payload = Base64.getDecoder().decode(packetData);
held = loader.readPacketNoDigest(payload, factory, null);
} catch (IllegalArgumentException e) {
throw new PacketException(e);
}
} }
} }
} }
@ -138,8 +181,13 @@ public class Base64Packet implements IStreamedPacket {
public void readData(OutputStream outputStream) throws IOException, PacketException { public void readData(OutputStream outputStream) throws IOException, PacketException {
if (outputStream == null) throw new NullPointerException("outputStream is null"); if (outputStream == null) throw new NullPointerException("outputStream is null");
synchronized (slock) { synchronized (slock) {
processEncryptedCache(); if (useCache) {
outputStream.write(encryptedCache); processEncryptedCache();
outputStream.write(encryptedCache);
} else {
if (held == null) throw new PacketException("no data");
loader.writePacketNoDigest(Base64.getEncoder().wrap(outputStream), held, true);
}
} }
} }
@ -172,8 +220,13 @@ public class Base64Packet implements IStreamedPacket {
@Override @Override
public int getSize() throws PacketException { public int getSize() throws PacketException {
synchronized (slock) { synchronized (slock) {
processEncryptedCache(); if (useCache) {
return encryptedCache.length; processEncryptedCache();
return encryptedCache.length;
} else {
if (held == null) throw new PacketException("no data");
return 4 * (int) Math.ceil((double) loader.getPacketSize(held, true, true) / 3);
}
} }
} }
@ -241,4 +294,26 @@ public class Base64Packet implements IStreamedPacket {
held = packet; held = packet;
} }
} }
/**
* Gets if the encrypted data is cached.
*
* @return If the encrypted data is cached.
*/
public boolean isCacheUsed() {
return useCache;
}
/**
* Sets if the encrypted data is cached.
*
* @param used If the encrypted data should be cached.
*/
public void setCacheUsed(boolean used) {
synchronized (slock) {
useCache = used;
if (!useCache)
encryptedCache = null;
}
}
} }