/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.blur.thirdparty.thrift_0_9_0; import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import org.apache.blur.thirdparty.thrift_0_9_0.protocol.TBinaryProtocol; import org.apache.blur.thirdparty.thrift_0_9_0.protocol.TField; import org.apache.blur.thirdparty.thrift_0_9_0.protocol.TProtocol; import org.apache.blur.thirdparty.thrift_0_9_0.protocol.TProtocolFactory; import org.apache.blur.thirdparty.thrift_0_9_0.protocol.TProtocolUtil; import org.apache.blur.thirdparty.thrift_0_9_0.protocol.TType; import org.apache.blur.thirdparty.thrift_0_9_0.transport.TMemoryInputTransport; /** * Generic utility for easily deserializing objects from a byte array or Java * String. * */ public class TDeserializer { private final TProtocol protocol_; private final TMemoryInputTransport trans_; /** * Create a new TDeserializer that uses the TBinaryProtocol by default. */ public TDeserializer() { this(new TBinaryProtocol.Factory()); } /** * Create a new TDeserializer. It will use the TProtocol specified by the * factory that is passed in. * * @param protocolFactory Factory to create a protocol */ public TDeserializer(TProtocolFactory protocolFactory) { trans_ = new TMemoryInputTransport(); protocol_ = protocolFactory.getProtocol(trans_); } /** * Deserialize the Thrift object from a byte array. * * @param base The object to read into * @param bytes The array to read from */ public void deserialize(TBase base, byte[] bytes) throws TException { try { trans_.reset(bytes); base.read(protocol_); } finally { trans_.clear(); protocol_.reset(); } } /** * Deserialize the Thrift object from a Java string, using a specified * character set for decoding. * * @param base The object to read into * @param data The string to read from * @param charset Valid JVM charset */ public void deserialize(TBase base, String data, String charset) throws TException { try { deserialize(base, data.getBytes(charset)); } catch (UnsupportedEncodingException uex) { throw new TException("JVM DOES NOT SUPPORT ENCODING: " + charset); } finally { protocol_.reset(); } } /** * Deserialize only a single Thrift object (addressed by recursively using field id) * from a byte record. * @param tb The object to read into * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path tb * @param fieldIdPathRest The rest FieldId's that define a path tb * @throws TException */ public void partialDeserialize(TBase tb, byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { try { if (locateField(bytes, fieldIdPathFirst, fieldIdPathRest) != null) { // if this line is reached, iprot will be positioned at the start of tb. tb.read(protocol_); } } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } /** * Deserialize only a boolean field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a boolean field * @param fieldIdPathRest The rest FieldId's that define a path to a boolean field * @throws TException */ public Boolean partialDeserializeBool(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Boolean) partialDeserializeField(TType.BOOL, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a byte field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a byte field * @param fieldIdPathRest The rest FieldId's that define a path to a byte field * @throws TException */ public Byte partialDeserializeByte(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Byte) partialDeserializeField(TType.BYTE, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a double field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a double field * @param fieldIdPathRest The rest FieldId's that define a path to a double field * @throws TException */ public Double partialDeserializeDouble(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Double) partialDeserializeField(TType.DOUBLE, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i16 field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i16 field * @param fieldIdPathRest The rest FieldId's that define a path to an i16 field * @throws TException */ public Short partialDeserializeI16(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Short) partialDeserializeField(TType.I16, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i32 field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i32 field * @param fieldIdPathRest The rest FieldId's that define a path to an i32 field * @throws TException */ public Integer partialDeserializeI32(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Integer) partialDeserializeField(TType.I32, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only an i64 field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to an i64 field * @param fieldIdPathRest The rest FieldId's that define a path to an i64 field * @throws TException */ public Long partialDeserializeI64(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (Long) partialDeserializeField(TType.I64, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a string field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a string field * @param fieldIdPathRest The rest FieldId's that define a path to a string field * @throws TException */ public String partialDeserializeString(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { return (String) partialDeserializeField(TType.STRING, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only a binary field (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a binary field * @param fieldIdPathRest The rest FieldId's that define a path to a binary field * @throws TException */ public ByteBuffer partialDeserializeByteArray(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { // TType does not have binary, so we use the arbitrary num 100 return (ByteBuffer) partialDeserializeField((byte)100, bytes, fieldIdPathFirst, fieldIdPathRest); } /** * Deserialize only the id of the field set in a TUnion (addressed by recursively using field id) * from a byte record. * @param bytes The serialized object to read from * @param fieldIdPathFirst First of the FieldId's that define a path to a TUnion * @param fieldIdPathRest The rest FieldId's that define a path to a TUnion * @throws TException */ public Short partialDeserializeSetFieldIdInUnion(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { try { TField field = locateField(bytes, fieldIdPathFirst, fieldIdPathRest); if (field != null){ protocol_.readStructBegin(); // The Union return protocol_.readFieldBegin().id; // The field set in the union } return null; } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } private Object partialDeserializeField(byte ttype, byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { try { TField field = locateField(bytes, fieldIdPathFirst, fieldIdPathRest); if (field != null) { // if this point is reached, iprot will be positioned at the start of the field. switch(ttype){ case TType.BOOL: if (field.type == TType.BOOL){ return protocol_.readBool(); } break; case TType.BYTE: if (field.type == TType.BYTE) { return protocol_.readByte(); } break; case TType.DOUBLE: if (field.type == TType.DOUBLE) { return protocol_.readDouble(); } break; case TType.I16: if (field.type == TType.I16) { return protocol_.readI16(); } break; case TType.I32: if (field.type == TType.I32) { return protocol_.readI32(); } break; case TType.I64: if (field.type == TType.I64) { return protocol_.readI64(); } break; case TType.STRING: if (field.type == TType.STRING) { return protocol_.readString(); } break; case 100: // hack to differentiate between string and binary if (field.type == TType.STRING) { return protocol_.readBinary(); } break; } } return null; } catch (Exception e) { throw new TException(e); } finally { trans_.clear(); protocol_.reset(); } } private TField locateField(byte[] bytes, TFieldIdEnum fieldIdPathFirst, TFieldIdEnum ... fieldIdPathRest) throws TException { trans_.reset(bytes); TFieldIdEnum[] fieldIdPath= new TFieldIdEnum[fieldIdPathRest.length + 1]; fieldIdPath[0] = fieldIdPathFirst; for (int i = 0; i < fieldIdPathRest.length; i++){ fieldIdPath[i + 1] = fieldIdPathRest[i]; } // index into field ID path being currently searched for int curPathIndex = 0; // this will be the located field, or null if it is not located TField field = null; protocol_.readStructBegin(); while (curPathIndex < fieldIdPath.length) { field = protocol_.readFieldBegin(); // we can stop searching if we either see a stop or we go past the field // id we're looking for (since fields should now be serialized in asc // order). if (field.type == TType.STOP || field.id > fieldIdPath[curPathIndex].getThriftFieldId()) { return null; } if (field.id != fieldIdPath[curPathIndex].getThriftFieldId()) { // Not the field we're looking for. Skip field. TProtocolUtil.skip(protocol_, field.type); protocol_.readFieldEnd(); } else { // This field is the next step in the path. Step into field. curPathIndex++; if (curPathIndex < fieldIdPath.length) { protocol_.readStructBegin(); } } } return field; } /** * Deserialize the Thrift object from a Java string, using the default JVM * charset encoding. * * @param base The object to read into * @param data The string to read from */ public void fromString(TBase base, String data) throws TException { deserialize(base, data.getBytes()); } }