package org.limewire.promotion.containers;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.limewire.io.BadGGEPBlockException;
import org.limewire.io.GGEP;
import org.limewire.io.IOUtils;
import org.limewire.util.StringUtils;
/**
* Wraps multiple messages into one message, generally so you can stuff a bunch
* of messages inside a {@link SignedMessageContainer}.
*/
public class MultiMessageContainer extends MapMessageContainer {
private static final String KEY_WRAPPED_BYTES = "W";
public byte[] getType() {
return StringUtils.toUTF8Bytes("MULT");
}
@Override
public void decode(final GGEP rawGGEP) throws BadGGEPBlockException {
if (!rawGGEP.hasValueFor(KEY_WRAPPED_BYTES))
throw new BadGGEPBlockException("Missing wrappedBytes");
super.decode(rawGGEP);
}
/**
* @return the wrapped bytes, or a new empty array if there is a problem
* loading the array
*/
private byte[] getWrappedBytes() {
final byte[] bytes = getBytes(KEY_WRAPPED_BYTES);
try {
if (bytes != null)
return IOUtils.inflate(bytes);
} catch (IOException ignored) {
}
return new byte[0];
}
/**
* @return a list of wrapped messages, in the same order they were added.
* This method does not cache results, so a second call will create
* a new list with new instances of the wrapped messages
*/
public List<MessageContainer> getWrappedMessages() {
final List<MessageContainer> list = new ArrayList<MessageContainer>();
final byte[] bytes = getWrappedBytes();
if (bytes.length > 0) {
final int[] nextOffset = new int[1];
int offset = 0;
final MessageContainerParser parser = new MessageContainerParser();
while (offset < bytes.length) {
try {
list.add(parser.parse(new GGEP(bytes, offset, nextOffset)));
offset = nextOffset[0];
} catch (BadGGEPBlockException ex) {
throw new RuntimeException("Parsing error: ", ex);
}
}
}
return list;
}
/**
* Takes the given list and encodes it into the wrapping system of this
* message, so later changes to the given list will NOT be reflected by this
* container.
*/
public void setWrappedMessages(final List<MessageContainer> messages) {
final ByteArrayOutputStream out = new ByteArrayOutputStream();
for (MessageContainer message : messages) {
try {
out.write(message.encode());
} catch (IOException ex) {
throw new RuntimeException("IOException? WTF?", ex);
}
}
put(KEY_WRAPPED_BYTES, IOUtils.deflate(out.toByteArray()));
}
}