Skip to content

Commit 0aaf4dc

Browse files
committed
JAVA-1258: Changed BSONReader and BSONWriter to interfaces, and added AbstractBSONReader and AbstractBSONWriter. Refactored AbstractBSONReader to pull more behavior up, to make it easier to write subclasses.
1 parent ced5b54 commit 0aaf4dc

15 files changed

Lines changed: 1437 additions & 1184 deletions

bson/src/main/org/bson/AbstractBSONReader.java

Lines changed: 662 additions & 0 deletions
Large diffs are not rendered by default.

bson/src/main/org/bson/AbstractBSONWriter.java

Lines changed: 497 additions & 0 deletions
Large diffs are not rendered by default.

bson/src/main/org/bson/BSONBinaryReader.java

Lines changed: 50 additions & 174 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,8 @@
2525

2626
import static java.lang.String.format;
2727

28-
public class BSONBinaryReader extends BSONReader {
28+
public class BSONBinaryReader extends AbstractBSONReader {
2929

30-
private Context context;
3130
private final InputBuffer buffer;
3231
private final boolean closeBuffer;
3332

@@ -38,7 +37,7 @@ public BSONBinaryReader(final BSONReaderSettings settings, final InputBuffer buf
3837
}
3938
this.buffer = buffer;
4039
this.closeBuffer = closeBuffer;
41-
context = new Context(null, BSONContextType.TOP_LEVEL, 0, 0);
40+
setContext(new Context(null, BSONContextType.TOP_LEVEL, 0, 0));
4241
}
4342

4443
public BSONBinaryReader(final InputBuffer buffer, final boolean closeBuffer) {
@@ -81,7 +80,7 @@ public BSONType readBSONType() {
8180
setCurrentBSONType(buffer.readBSONType());
8281

8382
if (getCurrentBSONType() == BSONType.END_OF_DOCUMENT) {
84-
switch (context.contextType) {
83+
switch (getContext().getContextType()) {
8584
case ARRAY:
8685
setState(State.END_OF_ARRAY);
8786
return BSONType.END_OF_DOCUMENT;
@@ -91,11 +90,11 @@ public BSONType readBSONType() {
9190
return BSONType.END_OF_DOCUMENT;
9291
default:
9392
String message = format("BSONType EndOfDocument is not valid when ContextType is %s.",
94-
context.contextType);
93+
getContext().getContextType());
9594
throw new BSONSerializationException(message);
9695
}
9796
} else {
98-
switch (context.contextType) {
97+
switch (getContext().getContextType()) {
9998
case ARRAY:
10099
buffer.skipCString(); // ignore array element names
101100
setState(State.VALUE);
@@ -114,10 +113,7 @@ public BSONType readBSONType() {
114113
}
115114

116115
@Override
117-
public Binary readBinaryData() {
118-
checkPreconditions("readBinaryData", BSONType.BINARY);
119-
setState(getNextState());
120-
116+
protected Binary doReadBinaryData() {
121117
int numBytes = buffer.readInt32();
122118
byte type = buffer.readByte();
123119

@@ -126,227 +122,131 @@ public Binary readBinaryData() {
126122
numBytes -= 4;
127123
}
128124

129-
byte[] data = buffer.readBytes(numBytes);
130-
return new Binary(type, data);
125+
return new Binary(type, buffer.readBytes(numBytes));
131126
}
132127

133128
@Override
134-
public boolean readBoolean() {
135-
checkPreconditions("readBoolean", BSONType.BOOLEAN);
136-
setState(getNextState());
129+
protected boolean doReadBoolean() {
137130
return buffer.readBoolean();
138131
}
139132

140133
@Override
141-
public long readDateTime() {
142-
checkPreconditions("readDateTime", BSONType.DATE_TIME);
143-
setState(getNextState());
134+
protected long doReadDateTime() {
144135
return buffer.readInt64();
145136
}
146137

147138
@Override
148-
public double readDouble() {
149-
checkPreconditions("readDouble", BSONType.DOUBLE);
150-
setState(getNextState());
139+
protected double doReadDouble() {
151140
return buffer.readDouble();
152141
}
153142

154143
@Override
155-
public int readInt32() {
156-
checkPreconditions("readInt32", BSONType.INT32);
157-
setState(getNextState());
144+
protected int doReadInt32() {
158145
return buffer.readInt32();
159146
}
160147

161148
@Override
162-
public long readInt64() {
163-
checkPreconditions("readInt64", BSONType.INT64);
164-
setState(getNextState());
149+
protected long doReadInt64() {
165150
return buffer.readInt64();
166151
}
167152

168153
@Override
169-
public String readJavaScript() {
170-
checkPreconditions("readJavaScript", BSONType.JAVASCRIPT);
171-
setState(getNextState());
154+
protected String doReadJavaScript() {
172155
return buffer.readString();
173156
}
174157

175158
@Override
176-
public String readJavaScriptWithScope() {
177-
checkPreconditions("readInt64", BSONType.JAVASCRIPT_WITH_SCOPE);
178-
setState(getNextState());
179-
159+
protected String doReadJavaScriptWithScope() {
180160
int startPosition = buffer.getPosition(); // position of size field
181161
int size = readSize();
182-
context = new Context(context, BSONContextType.JAVASCRIPT_WITH_SCOPE, startPosition, size);
183-
String code = buffer.readString();
184-
185-
setState(State.SCOPE_DOCUMENT);
186-
return code;
162+
setContext(new Context(getContext(), BSONContextType.JAVASCRIPT_WITH_SCOPE, startPosition, size));
163+
return buffer.readString();
187164
}
188165

189166
@Override
190-
public void readMaxKey() {
191-
checkPreconditions("readMaxKey", BSONType.MAX_KEY);
192-
setState(getNextState());
167+
protected void doReadMaxKey() {
193168
}
194169

195170
@Override
196-
public void readMinKey() {
197-
checkPreconditions("readMinKey", BSONType.MIN_KEY);
198-
setState(getNextState());
171+
protected void doReadMinKey() {
199172
}
200173

201174
@Override
202-
public void readNull() {
203-
checkPreconditions("readNull", BSONType.NULL);
204-
setState(getNextState());
175+
protected void doReadNull() {
205176
}
206177

207178
@Override
208-
public ObjectId readObjectId() {
209-
checkPreconditions("readObjectId", BSONType.OBJECT_ID);
210-
setState(getNextState());
179+
protected ObjectId doReadObjectId() {
211180
return buffer.readObjectId();
212181
}
213182

214183
@Override
215-
public RegularExpression readRegularExpression() {
216-
checkPreconditions("readRegularExpression", BSONType.REGULAR_EXPRESSION);
217-
setState(getNextState());
184+
protected RegularExpression doReadRegularExpression() {
218185
return new RegularExpression(buffer.readCString(), buffer.readCString());
219186
}
220187

221188
@Override
222-
public DBPointer readDBPointer() {
223-
checkPreconditions("readDBPointer", BSONType.DB_POINTER);
224-
setState(getNextState());
189+
protected DBPointer doReadDBPointer() {
225190
buffer.readInt32(); //according to 2.x namespace is preceded by integer - length of namespace
226191
return new DBPointer(buffer.readCString(), buffer.readObjectId());
227192
}
228193

229194
@Override
230-
public String readString() {
231-
checkPreconditions("readString", BSONType.STRING);
232-
setState(getNextState());
195+
protected String doReadString() {
233196
return buffer.readString();
234197
}
235198

236199
@Override
237-
public String readSymbol() {
238-
checkPreconditions("readSymbol", BSONType.SYMBOL);
239-
setState(getNextState());
200+
protected String doReadSymbol() {
240201
return buffer.readString();
241202
}
242203

243204
@Override
244-
public Timestamp readTimestamp() {
245-
checkPreconditions("readTimestamp", BSONType.TIMESTAMP);
246-
setState(getNextState());
205+
protected Timestamp doReadTimestamp() {
247206
int increment = buffer.readInt32();
248207
int time = buffer.readInt32();
249208
return new Timestamp(time, increment);
250209
}
251210

252211
@Override
253-
public void readUndefined() {
254-
checkPreconditions("readUndefined", BSONType.UNDEFINED);
255-
setState(getNextState());
212+
protected void doReadUndefined() {
256213
}
257214

258215
@Override
259-
public void readStartArray() {
260-
checkPreconditions("readStartArray", BSONType.ARRAY);
261-
216+
public void doReadStartArray() {
262217
int startPosition = buffer.getPosition(); // position of size field
263218
int size = readSize();
264-
context = new Context(context, BSONContextType.ARRAY, startPosition, size);
265-
setState(State.TYPE);
219+
setContext(new Context(getContext(), BSONContextType.ARRAY, startPosition, size));
266220
}
267221

268222
@Override
269-
public void readStartDocument() {
270-
checkPreconditions("readStartDocument", BSONType.DOCUMENT);
271-
223+
protected void doReadStartDocument() {
272224
BSONContextType contextType = (getState() == State.SCOPE_DOCUMENT)
273225
? BSONContextType.SCOPE_DOCUMENT : BSONContextType.DOCUMENT;
274226
int startPosition = buffer.getPosition(); // position of size field
275227
int size = readSize();
276-
context = new Context(context, contextType, startPosition, size);
277-
setState(State.TYPE);
228+
setContext(new Context(getContext(), contextType, startPosition, size));
278229
}
279230

280231
@Override
281-
public void readEndArray() {
282-
if (isClosed()) {
283-
throw new IllegalStateException("BSONBinaryWriter");
284-
}
285-
if (context.contextType != BSONContextType.ARRAY) {
286-
throwInvalidContextType("readEndArray", context.contextType, BSONContextType.ARRAY);
287-
}
288-
if (getState() == State.TYPE) {
289-
readBSONType(); // will set state to EndOfArray if at end of array
290-
}
291-
if (getState() != State.END_OF_ARRAY) {
292-
throwInvalidState("ReadEndArray", State.END_OF_ARRAY);
293-
}
294-
295-
context = context.popContext(buffer.getPosition());
296-
setStateOnEnd();
232+
protected void doReadEndArray() {
233+
setContext(getContext().popContext(buffer.getPosition()));
297234
}
298235

299236
@Override
300-
public void readEndDocument() {
301-
if (isClosed()) {
302-
throw new IllegalStateException("BSONBinaryWriter");
303-
}
304-
if (context.contextType != BSONContextType.DOCUMENT && context.contextType != BSONContextType.SCOPE_DOCUMENT) {
305-
throwInvalidContextType("readEndDocument", context.contextType, BSONContextType.DOCUMENT, BSONContextType.SCOPE_DOCUMENT);
306-
}
307-
if (getState() == State.TYPE) {
308-
readBSONType(); // will set state to EndOfDocument if at end of document
309-
}
310-
if (getState() != State.END_OF_DOCUMENT) {
311-
throwInvalidState("readEndDocument", State.END_OF_DOCUMENT);
312-
}
313-
314-
context = context.popContext(buffer.getPosition());
315-
if (context.contextType == BSONContextType.JAVASCRIPT_WITH_SCOPE) {
316-
context = context.popContext(buffer.getPosition()); // JavaScriptWithScope
317-
}
318-
319-
setStateOnEnd();
320-
}
321-
322-
private void setStateOnEnd() {
323-
switch (context.contextType) {
324-
case ARRAY:
325-
case DOCUMENT:
326-
setState(State.TYPE);
327-
break;
328-
case TOP_LEVEL:
329-
setState(State.DONE);
330-
break;
331-
default:
332-
throw new BSONException(format("Unexpected ContextType %s.", context.contextType));
237+
protected void doReadEndDocument() {
238+
setContext(getContext().popContext(buffer.getPosition()));
239+
if (getContext().getContextType() == BSONContextType.JAVASCRIPT_WITH_SCOPE) {
240+
setContext(getContext().popContext(buffer.getPosition())); // JavaScriptWithScope
333241
}
334242
}
335243

336244
@Override
337-
public void skipName() {
338-
if (isClosed()) {
339-
throw new IllegalStateException("BSONBinaryWriter");
340-
}
341-
if (getState() != State.NAME) {
342-
throwInvalidState("skipName", State.NAME);
343-
}
344-
345-
setState(State.VALUE);
245+
protected void doSkipName() {
346246
}
347247

348248
@Override
349-
public void skipValue() {
249+
protected void doSkipValue() {
350250
if (isClosed()) {
351251
throw new IllegalStateException("BSONBinaryWriter");
352252
}
@@ -423,27 +323,6 @@ public void skipValue() {
423323
setState(State.TYPE);
424324
}
425325

426-
private void checkPreconditions(final String methodName, final BSONType type) {
427-
if (isClosed()) {
428-
throw new IllegalStateException("BSONBinaryWriter");
429-
}
430-
431-
verifyBSONType(methodName, type);
432-
}
433-
434-
private State getNextState() {
435-
switch (context.contextType) {
436-
case ARRAY:
437-
case DOCUMENT:
438-
case SCOPE_DOCUMENT:
439-
return State.TYPE;
440-
case TOP_LEVEL:
441-
return State.DONE;
442-
default:
443-
throw new BSONException(format("Unexpected ContextType %s.", context.contextType));
444-
}
445-
}
446-
447326
private int readSize() {
448327
int size = buffer.readInt32();
449328
if (size < 0) {
@@ -453,36 +332,33 @@ private int readSize() {
453332
return size;
454333
}
455334

335+
protected Context getContext() {
336+
return (Context) super.getContext();
337+
}
338+
456339

457-
private static class Context {
458-
private final Context parentContext;
459-
private final BSONContextType contextType;
340+
private static class Context extends AbstractBSONReader.Context {
460341
private final int startPosition;
461342
private final int size;
462343

463344
Context(final Context parentContext, final BSONContextType contextType, final int startPosition, final int size) {
464-
this.parentContext = parentContext;
465-
this.contextType = contextType;
345+
super(parentContext, contextType);
466346
this.startPosition = startPosition;
467347
this.size = size;
468348
}
469349

470-
/**
471-
* Creates a clone of the context.
472-
*
473-
* @return A clone of the context.
474-
*/
475-
public Context copy() {
476-
return new Context(parentContext, contextType, startPosition, size);
477-
}
478-
479350
Context popContext(final int position) {
480351
int actualSize = position - startPosition;
481352
if (actualSize != size) {
482353
String message = format("Expected size to be %d, not %d.", size, actualSize);
483354
throw new BSONSerializationException(message);
484355
}
485-
return parentContext;
356+
return getParentContext();
357+
}
358+
359+
@Override
360+
protected Context getParentContext() {
361+
return (Context) super.getParentContext();
486362
}
487363
}
488364
}

0 commit comments

Comments
 (0)