Skip to content

Commit b4497cb

Browse files
committed
msgpack#100 Using immutable fields and a builder for Config object
1 parent 413a28d commit b4497cb

File tree

3 files changed

+151
-38
lines changed

3 files changed

+151
-38
lines changed

msgpack-core/src/main/java/org/msgpack/core/MessagePack.java

Lines changed: 134 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
import java.nio.charset.Charset;
44
import java.nio.charset.CodingErrorAction;
55

6+
import static org.msgpack.core.Preconditions.checkArgument;
7+
68
/**
79
* Includes MessagePack codes
810
*
@@ -15,35 +17,147 @@ public class MessagePack {
1517
* Message packer/unpacker configuration object
1618
*/
1719
public static class Config {
20+
private final boolean readStringAsBinary;
21+
private final boolean readBinaryAsString;
22+
private final CodingErrorAction onMalFormedInput;
23+
private final CodingErrorAction onUnmappableCharacter;
24+
private final int maxUnpackStringSize;
25+
private final int stringEncoderBufferSize;
26+
private final int stringDecoderBufferSize;
27+
private final int packerBufferSize;
28+
private final int packerRawDataCopyingThreshold;
29+
30+
public Config(
31+
boolean readStringAsBinary,
32+
boolean readBinaryAsString,
33+
CodingErrorAction onMalFormedInput,
34+
CodingErrorAction onUnmappableCharacter,
35+
int maxUnpackStringSize,
36+
int stringEncoderBufferSize,
37+
int stringDecoderBufferSize,
38+
int packerBufferSize,
39+
int packerRawDataCopyingThreshold) {
40+
41+
checkArgument(packerBufferSize > 0, "packer buffer size must be larger than 0: " + packerBufferSize);
42+
checkArgument(stringEncoderBufferSize > 0, "string encoder buffer size must be larger than 0: " + stringEncoderBufferSize);
43+
checkArgument(stringDecoderBufferSize > 0, "string decoder buffer size must be larger than 0: " + stringDecoderBufferSize);
44+
45+
this.readStringAsBinary = readStringAsBinary;
46+
this.readBinaryAsString = readBinaryAsString;
47+
this.onMalFormedInput = onMalFormedInput;
48+
this.onUnmappableCharacter = onUnmappableCharacter;
49+
this.maxUnpackStringSize = maxUnpackStringSize;
50+
this.stringEncoderBufferSize = stringEncoderBufferSize;
51+
this.stringDecoderBufferSize = stringDecoderBufferSize;
52+
this.packerBufferSize = packerBufferSize;
53+
this.packerRawDataCopyingThreshold = packerRawDataCopyingThreshold;
54+
}
1855

19-
// allow unpackBinaryHeader to read str format family // default:true
20-
public boolean READ_STR_FORMAT_FAMILY_IN_UNPACK_BINARY_HEADER = true;
21-
22-
// allow unpackRawStringHeader and unpackString to read bin format family // default: true
23-
public boolean READ_BIN_FORMAT_FAMILY_IN_UNPACK_RAW_STRING_HEADER = true;
24-
25-
// Action when encountered a malformed input
26-
public CodingErrorAction MALFORMED_INPUT_ACTION = CodingErrorAction.REPORT;
27-
28-
// Action when a unmappable character is found
29-
public CodingErrorAction UNMAPPABLE_CHARACTER_ACTION = CodingErrorAction.REPORT;
30-
31-
// unpackString size limit // default: Integer.MAX_VALUE
32-
public int MAX_SIZE_UNPACK_STRING = Integer.MAX_VALUE;
56+
/**
57+
* allow unpackBinaryHeader to read str format family (default:true)
58+
*/
59+
public boolean isReadStringAsBinary() { return readStringAsBinary; }
60+
61+
/**
62+
* allow unpackRawStringHeader and unpackString to read bin format family (default: true)
63+
*/
64+
public boolean isReadBinaryAsString() { return readBinaryAsString; }
65+
/**
66+
* Action when encountered a malformed input
67+
*/
68+
public CodingErrorAction getActionOnMalFormedInput() { return onMalFormedInput; }
69+
/**
70+
* Action when an unmappable character is found
71+
*/
72+
public CodingErrorAction getActionOnUnmappableCharacter() { return onUnmappableCharacter; }
73+
74+
/**
75+
* unpackString size limit. (default: Integer.MAX_VALUE)
76+
*/
77+
public int getMaxUnpackStringSize() { return maxUnpackStringSize; }
78+
79+
public int getStringEncoderBufferSize() { return stringEncoderBufferSize; }
80+
public int getStringDecoderBufferSize() { return stringDecoderBufferSize; }
81+
82+
public int getPackerBufferSize() { return packerBufferSize; }
83+
public int getPackerRawDataCopyingThreshold() { return packerRawDataCopyingThreshold; }
84+
}
3385

34-
public int STRING_ENCODER_BUFFER_SIZE = 8192;
86+
/**
87+
* Builder of the configuration object
88+
*/
89+
public static class ConfigBuilder {
90+
91+
private boolean readStringAsBinary = true;
92+
private boolean readBinaryAsString = true;
93+
94+
private CodingErrorAction onMalFormedInput = CodingErrorAction.REPORT;
95+
private CodingErrorAction onUnmappableCharacter = CodingErrorAction.REPORT;
96+
97+
private int maxUnpackStringSize = Integer.MAX_VALUE;
98+
private int stringEncoderBufferSize = 8192;
99+
private int stringDecoderBufferSize = 8192;
100+
private int packerBufferSize = 8192;
101+
private int packerRawDataCopyingThreshold = 512;
102+
103+
public Config build() {
104+
return new Config(
105+
readStringAsBinary,
106+
readBinaryAsString,
107+
onMalFormedInput,
108+
onUnmappableCharacter,
109+
maxUnpackStringSize,
110+
stringEncoderBufferSize,
111+
stringDecoderBufferSize,
112+
packerBufferSize,
113+
packerRawDataCopyingThreshold
114+
);
115+
}
35116

36-
public int STRING_DECODER_BUFFER_SIZE = 8192;
117+
public ConfigBuilder readStringAsBinary(boolean enable) {
118+
this.readStringAsBinary = enable;
119+
return this;
120+
}
121+
public ConfigBuilder readBinaryAsString(boolean enable) {
122+
this.readBinaryAsString = enable;
123+
return this;
124+
}
125+
public ConfigBuilder onMalFormedInput(CodingErrorAction action) {
126+
this.onMalFormedInput = action;
127+
return this;
128+
}
129+
public ConfigBuilder onUnmappableCharacter(CodingErrorAction action) {
130+
this.onUnmappableCharacter = action;
131+
return this;
132+
}
133+
public ConfigBuilder maxUnpackStringSize(int size){
134+
this.maxUnpackStringSize = size;
135+
return this;
136+
}
137+
public ConfigBuilder stringEncoderBufferSize(int size) {
138+
this.stringEncoderBufferSize = size;
139+
return this;
140+
}
141+
public ConfigBuilder stringDecoderBufferSize(int size) {
142+
this.stringDecoderBufferSize = size;
143+
return this;
144+
}
145+
public ConfigBuilder packerBufferSize(int size) {
146+
this.packerBufferSize = size;
147+
return this;
148+
}
149+
public ConfigBuilder packerRawDataCopyingThreshold(int threshold) {
150+
this.packerRawDataCopyingThreshold = threshold;
151+
return this;
152+
}
153+
}
37154

38-
public int PACKER_BUFFER_SIZE = 8192;
39155

40-
public int PACKER_FLUSH_THRESHOLD = 512;
41-
}
42156

43157
/**
44158
* Default configuration, which is visible only from classes in the core package.
45159
*/
46-
static final Config DEFAULT_CONFIG = new Config();
160+
static final Config DEFAULT_CONFIG = new ConfigBuilder().build();
47161

48162

49163
/**

msgpack-core/src/main/java/org/msgpack/core/MessagePacker.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -81,18 +81,16 @@ public MessagePacker(MessageBufferOutput out) {
8181

8282
public MessagePacker(MessageBufferOutput out, MessagePack.Config config) {
8383
this.config = checkNotNull(config, "config is null");
84-
checkArgument(config.PACKER_BUFFER_SIZE > 0, "packer buffer size must be larger than 0: " + config.PACKER_BUFFER_SIZE);
85-
checkArgument(config.STRING_ENCODER_BUFFER_SIZE > 0, "string encoder buffer size must be larger than 0: " + config.STRING_ENCODER_BUFFER_SIZE);
8684
this.out = checkNotNull(out, "MessageBufferOutput is null");
87-
this.buffer = MessageBuffer.newDirectBuffer(config.PACKER_BUFFER_SIZE);
85+
this.buffer = MessageBuffer.newDirectBuffer(config.getPackerBufferSize());
8886
this.position = 0;
8987
}
9088

9189

9290
private void prepareEncoder() {
9391
if(encoder == null) {
94-
this.encodeBuffer = ByteBuffer.allocate(config.STRING_ENCODER_BUFFER_SIZE);
95-
this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.MALFORMED_INPUT_ACTION).onUnmappableCharacter(config.UNMAPPABLE_CHARACTER_ACTION);
92+
this.encodeBuffer = ByteBuffer.allocate(config.getStringEncoderBufferSize());
93+
this.encoder = MessagePack.UTF8.newEncoder().onMalformedInput(config.getActionOnMalFormedInput()).onUnmappableCharacter(config.getActionOnMalFormedInput());
9694
}
9795
}
9896

@@ -343,9 +341,9 @@ public MessagePacker packString(String s) throws IOException {
343341
}
344342

345343
if(cr.isError()) {
346-
if(cr.isMalformed() && config.MALFORMED_INPUT_ACTION == CodingErrorAction.REPORT) {
344+
if(cr.isMalformed() && config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) {
347345
cr.throwException();
348-
} else if(cr.isUnderflow() && config.MALFORMED_INPUT_ACTION == CodingErrorAction.REPORT) {
346+
} else if(cr.isUnderflow() && config.getActionOnUnmappableCharacter() == CodingErrorAction.REPORT) {
349347
cr.throwException();
350348
}
351349
}
@@ -452,7 +450,7 @@ public MessagePacker packRawStringHeader(int len) throws IOException {
452450

453451

454452
public MessagePacker writePayload(ByteBuffer src) throws IOException {
455-
if(src.remaining() >= config.PACKER_FLUSH_THRESHOLD) {
453+
if(src.remaining() >= config.getPackerRawDataCopyingThreshold()) {
456454
// Use the source ByteBuffer directly to avoid memory copy
457455

458456
// First, flush the current buffer contents
@@ -482,7 +480,7 @@ public MessagePacker writePayload(byte[] src) throws IOException {
482480
}
483481

484482
public MessagePacker writePayload(byte[] src, int off, int len) throws IOException {
485-
if(len >= config.PACKER_FLUSH_THRESHOLD) {
483+
if(len >= config.getPackerRawDataCopyingThreshold()) {
486484
// Use the input array directory to avoid memory copy
487485

488486
// Flush the current buffer contents

msgpack-core/src/main/java/org/msgpack/core/MessageUnpacker.java

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -149,10 +149,10 @@ public MessageUnpacker(MessageBufferInput in, MessagePack.Config config) {
149149

150150
private void prepareDecoder() {
151151
if(decoder == null) {
152-
decodeBuffer = CharBuffer.allocate(config.STRING_DECODER_BUFFER_SIZE);
152+
decodeBuffer = CharBuffer.allocate(config.getStringDecoderBufferSize());
153153
decoder = MessagePack.UTF8.newDecoder()
154-
.onMalformedInput(config.MALFORMED_INPUT_ACTION)
155-
.onUnmappableCharacter(config.UNMAPPABLE_CHARACTER_ACTION);
154+
.onMalformedInput(config.getActionOnMalFormedInput())
155+
.onUnmappableCharacter(config.getActionOnUnmappableCharacter());
156156
}
157157
}
158158

@@ -793,8 +793,9 @@ public double unpackDouble() throws IOException {
793793
public String unpackString() throws IOException {
794794
int strLen = unpackRawStringHeader();
795795
if(strLen > 0) {
796-
if(strLen > config.MAX_SIZE_UNPACK_STRING)
797-
throw new MessageSizeException(String.format("cannot unpackString of size larger than %,d", config.MAX_SIZE_UNPACK_STRING), config.MAX_SIZE_UNPACK_STRING);
796+
if(strLen > config.getMaxUnpackStringSize()) {
797+
throw new MessageSizeException(String.format("cannot unpack a String of size larger than %,d: %,d", config.getMaxUnpackStringSize(), strLen), strLen);
798+
}
798799

799800
prepareDecoder();
800801
assert(decoder != null);
@@ -825,9 +826,9 @@ public String unpackString() throws IOException {
825826
}
826827

827828
if(cr.isError()) {
828-
if(cr.isMalformed() && config.MALFORMED_INPUT_ACTION == CodingErrorAction.REPORT) {
829+
if(cr.isMalformed() && config.getActionOnMalFormedInput() == CodingErrorAction.REPORT) {
829830
cr.throwException();
830-
} else if(cr.isUnmappable() && config.UNMAPPABLE_CHARACTER_ACTION == CodingErrorAction.REPORT) {
831+
} else if(cr.isUnmappable() && config.getActionOnUnmappableCharacter() == CodingErrorAction.REPORT) {
831832
cr.throwException();
832833
}
833834
}
@@ -948,7 +949,7 @@ public int unpackRawStringHeader() throws IOException {
948949
if(len >= 0)
949950
return len;
950951

951-
if(config.READ_BIN_FORMAT_FAMILY_IN_UNPACK_RAW_STRING_HEADER) {
952+
if(config.isReadBinaryAsString()){
952953
len = readBinaryHeader(b);
953954
if(len >= 0)
954955
return len;
@@ -966,7 +967,7 @@ public int unpackBinaryHeader() throws IOException {
966967
if(len >= 0)
967968
return len;
968969

969-
if(config.READ_STR_FORMAT_FAMILY_IN_UNPACK_BINARY_HEADER) {
970+
if(config.isReadStringAsBinary()) {
970971
len = readStringHeader(b);
971972
if(len >= 0)
972973
return len;

0 commit comments

Comments
 (0)