Skip to content

Instantly share code, notes, and snippets.

@nickman
Created August 28, 2018 18:45
Show Gist options
  • Save nickman/bc08be142de0b15c5bcdca9adfbf596d to your computer and use it in GitHub Desktop.
Save nickman/bc08be142de0b15c5bcdca9adfbf596d to your computer and use it in GitHub Desktop.
ReplayingDecoder to read a sequence of uploaded files
/**
*
*/
package net.example;
import java.nio.charset.Charset;
import java.util.List;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.ReplayingDecoder;
public class FileUploadReplayingDecoder extends ReplayingDecoder<FileUploadReplayingDecoder.FileUploadField> {
public static final Charset UTF8 = Charset.forName("UTF8");
protected int fileNumber = -1;
protected int filesRead = 0;
protected int nextSize = -1;
protected int nameSize = -1;
protected byte[] nameBytes = null;
protected String fileName = null;
public FileUploadReplayingDecoder() {
super(FileUploadField.NUMBER);
}
public static class Upload {
public String fileName = null;
public ByteBuf content = null;
Upload(String fileName, ByteBuf content) {
super();
this.fileName = fileName;
this.content = content;
}
}
public static enum FileUploadField {
NUMBER,
SIZE,
NAME_SIZE,
NAME,
CONTENT;
}
@Override
protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
switch(state()) {
case NUMBER:
fileNumber = in.readInt();
checkpoint(FileUploadField.SIZE);
case SIZE:
nextSize = in.readInt();
checkpoint(FileUploadField.NAME_SIZE);
case NAME_SIZE:
nameSize = in.readInt();
nameBytes = new byte[nameSize];
checkpoint(FileUploadField.NAME);
case NAME:
in.readBytes(nameBytes);
fileName = new String(nameBytes, UTF8);
checkpoint(FileUploadField.CONTENT);
case CONTENT:
// Need to ReferenceCountUtil.release(fileContent) after use.
ByteBuf fileContent = in.readBytes(nextSize);
out.add(new Upload(fileName, fileContent));
filesRead++;
if(filesRead == fileNumber) {
ctx.pipeline().remove(this);
} else {
checkpoint(FileUploadField.SIZE);
}
break;
default:
throw new Error("Shouldn't reach here.");
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment