Simplify XContent detection.

Currently we duplicate the logic for BytesReferences and InputStreams.
This commit is contained in:
Adrien Grand 2015-11-03 11:10:45 +01:00
parent 48ee09fbd4
commit c350a3dfae
1 changed files with 4 additions and 60 deletions

View File

@ -25,6 +25,7 @@ import com.fasterxml.jackson.dataformat.smile.SmileConstants;
import org.elasticsearch.ElasticsearchParseException;
import org.elasticsearch.common.bytes.BytesArray;
import org.elasticsearch.common.bytes.BytesReference;
import org.elasticsearch.common.io.Streams;
import org.elasticsearch.common.xcontent.cbor.CborXContent;
import org.elasticsearch.common.xcontent.json.JsonXContent;
import org.elasticsearch.common.xcontent.smile.SmileXContent;
@ -33,7 +34,6 @@ import org.elasticsearch.common.xcontent.yaml.YamlXContent;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Arrays;
/**
* A one stop to use {@link org.elasticsearch.common.xcontent.XContent} and {@link XContentBuilder}.
@ -216,65 +216,9 @@ public class XContentFactory {
}
si.mark(GUESS_HEADER_LENGTH);
try {
final int firstInt = si.read(); // this must be an int since we need to respect the method contract
if (firstInt == -1) {
return null;
}
final int secondInt = si.read(); // this must be an int since we need to respect the method contract
if (secondInt == -1) {
return null;
}
final byte first = (byte) (0xff & firstInt);
final byte second = (byte) (0xff & secondInt);
if (first == SmileConstants.HEADER_BYTE_1 && second == SmileConstants.HEADER_BYTE_2) {
int third = si.read();
if (third == SmileConstants.HEADER_BYTE_3) {
return XContentType.SMILE;
}
}
if (first == '{' || second == '{') {
return XContentType.JSON;
}
if (first == '-' && second == '-') {
int third = si.read();
if (third == '-') {
return XContentType.YAML;
}
}
// CBOR logic similar to CBORFactory#hasCBORFormat
if (first == CBORConstants.BYTE_OBJECT_INDEFINITE){
return XContentType.CBOR;
}
if (CBORConstants.hasMajorType(CBORConstants.MAJOR_TYPE_TAG, first)) {
// Actually, specific "self-describe tag" is a very good indicator
int third = si.read();
if (third == -1) {
return null;
}
if (first == (byte) 0xD9 && second == (byte) 0xD9 && third == (byte) 0xF7) {
return XContentType.CBOR;
}
}
// for small objects, some encoders just encode as major type object, we can safely
// say its CBOR since it doesn't contradict SMILE or JSON, and its a last resort
if (CBORConstants.hasMajorType(CBORConstants.MAJOR_TYPE_OBJECT, first)) {
return XContentType.CBOR;
}
for (int i = 2; i < GUESS_HEADER_LENGTH; i++) {
int val = si.read();
if (val == -1) {
return null;
}
if (val == '{') {
return XContentType.JSON;
}
if (Character.isWhitespace(val) == false) {
break;
}
}
return null;
final byte[] firstBytes = new byte[GUESS_HEADER_LENGTH];
final int read = Streams.readFully(si, firstBytes);
return xContentType(new BytesArray(firstBytes, 0, read));
} finally {
si.reset();
}