/**
 * Autogenerated by Thrift Compiler (0.9.0)
 *
 * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING
 *  @generated
 */
package org.apache.hadoop.thriftfs.api;

import org.apache.thrift.scheme.IScheme;
import org.apache.thrift.scheme.SchemeFactory;
import org.apache.thrift.scheme.StandardScheme;

import org.apache.thrift.scheme.TupleScheme;
import org.apache.thrift.protocol.TTupleProtocol;
import org.apache.thrift.protocol.TProtocolException;
import org.apache.thrift.EncodingUtils;
import org.apache.thrift.TException;
import java.util.List;
import java.util.ArrayList;
import java.util.Map;
import java.util.HashMap;
import java.util.EnumMap;
import java.util.Set;
import java.util.HashSet;
import java.util.EnumSet;
import java.util.Collections;
import java.util.BitSet;
import java.nio.ByteBuffer;
import java.util.Arrays;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * Representation of a file block in HDFS
 * 
 * Modelled after org.apache.hadoop.hdfs.protocol.LocatedBlock
 */
public class Block implements org.apache.thrift.TBase<Block, Block._Fields>, java.io.Serializable, Cloneable {
  private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("Block");

  private static final org.apache.thrift.protocol.TField BLOCK_ID_FIELD_DESC = new org.apache.thrift.protocol.TField("blockId", org.apache.thrift.protocol.TType.I64, (short)1);
  private static final org.apache.thrift.protocol.TField PATH_FIELD_DESC = new org.apache.thrift.protocol.TField("path", org.apache.thrift.protocol.TType.STRING, (short)2);
  private static final org.apache.thrift.protocol.TField NUM_BYTES_FIELD_DESC = new org.apache.thrift.protocol.TField("numBytes", org.apache.thrift.protocol.TType.I64, (short)3);
  private static final org.apache.thrift.protocol.TField GEN_STAMP_FIELD_DESC = new org.apache.thrift.protocol.TField("genStamp", org.apache.thrift.protocol.TType.I64, (short)4);
  private static final org.apache.thrift.protocol.TField NODES_FIELD_DESC = new org.apache.thrift.protocol.TField("nodes", org.apache.thrift.protocol.TType.LIST, (short)5);
  private static final org.apache.thrift.protocol.TField START_OFFSET_FIELD_DESC = new org.apache.thrift.protocol.TField("startOffset", org.apache.thrift.protocol.TType.I64, (short)6);
  private static final org.apache.thrift.protocol.TField TOKEN_FIELD_DESC = new org.apache.thrift.protocol.TField("token", org.apache.thrift.protocol.TType.STRING, (short)7);

  private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
  static {
    schemes.put(StandardScheme.class, new BlockStandardSchemeFactory());
    schemes.put(TupleScheme.class, new BlockTupleSchemeFactory());
  }

  /**
   * Block ID (unique among all blocks in a filesystem).
   */
  public long blockId; // required
  /**
   * Path of the file which this block belongs to.
   */
  public String path; // required
  /**
   * Length of this block.
   */
  public long numBytes; // required
  /**
   * Generational stamp of this block.
   */
  public long genStamp; // required
  /**
   * List of data nodes with copies  of this block.
   */
  public List<DatanodeInfo> nodes; // required
  /**
   * Offset of the first byte of the block relative to the start of the file
   */
  public long startOffset; // required
  /**
   * The serialized token associated with this block.
   */
  public String token; // required

  /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
  public enum _Fields implements org.apache.thrift.TFieldIdEnum {
    /**
     * Block ID (unique among all blocks in a filesystem).
     */
    BLOCK_ID((short)1, "blockId"),
    /**
     * Path of the file which this block belongs to.
     */
    PATH((short)2, "path"),
    /**
     * Length of this block.
     */
    NUM_BYTES((short)3, "numBytes"),
    /**
     * Generational stamp of this block.
     */
    GEN_STAMP((short)4, "genStamp"),
    /**
     * List of data nodes with copies  of this block.
     */
    NODES((short)5, "nodes"),
    /**
     * Offset of the first byte of the block relative to the start of the file
     */
    START_OFFSET((short)6, "startOffset"),
    /**
     * The serialized token associated with this block.
     */
    TOKEN((short)7, "token");

    private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();

    static {
      for (_Fields field : EnumSet.allOf(_Fields.class)) {
        byName.put(field.getFieldName(), field);
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, or null if its not found.
     */
    public static _Fields findByThriftId(int fieldId) {
      switch(fieldId) {
        case 1: // BLOCK_ID
          return BLOCK_ID;
        case 2: // PATH
          return PATH;
        case 3: // NUM_BYTES
          return NUM_BYTES;
        case 4: // GEN_STAMP
          return GEN_STAMP;
        case 5: // NODES
          return NODES;
        case 6: // START_OFFSET
          return START_OFFSET;
        case 7: // TOKEN
          return TOKEN;
        default:
          return null;
      }
    }

    /**
     * Find the _Fields constant that matches fieldId, throwing an exception
     * if it is not found.
     */
    public static _Fields findByThriftIdOrThrow(int fieldId) {
      _Fields fields = findByThriftId(fieldId);
      if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
      return fields;
    }

    /**
     * Find the _Fields constant that matches name, or null if its not found.
     */
    public static _Fields findByName(String name) {
      return byName.get(name);
    }

    private final short _thriftId;
    private final String _fieldName;

    _Fields(short thriftId, String fieldName) {
      _thriftId = thriftId;
      _fieldName = fieldName;
    }

    public short getThriftFieldId() {
      return _thriftId;
    }

    public String getFieldName() {
      return _fieldName;
    }
  }

  // isset id assignments
  private static final int __BLOCKID_ISSET_ID = 0;
  private static final int __NUMBYTES_ISSET_ID = 1;
  private static final int __GENSTAMP_ISSET_ID = 2;
  private static final int __STARTOFFSET_ISSET_ID = 3;
  private byte __isset_bitfield = 0;
  public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
  static {
    Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
    tmpMap.put(_Fields.BLOCK_ID, new org.apache.thrift.meta_data.FieldMetaData("blockId", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.PATH, new org.apache.thrift.meta_data.FieldMetaData("path", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    tmpMap.put(_Fields.NUM_BYTES, new org.apache.thrift.meta_data.FieldMetaData("numBytes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.GEN_STAMP, new org.apache.thrift.meta_data.FieldMetaData("genStamp", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.NODES, new org.apache.thrift.meta_data.FieldMetaData("nodes", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
            new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, DatanodeInfo.class))));
    tmpMap.put(_Fields.START_OFFSET, new org.apache.thrift.meta_data.FieldMetaData("startOffset", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.I64)));
    tmpMap.put(_Fields.TOKEN, new org.apache.thrift.meta_data.FieldMetaData("token", org.apache.thrift.TFieldRequirementType.DEFAULT, 
        new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING)));
    metaDataMap = Collections.unmodifiableMap(tmpMap);
    org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(Block.class, metaDataMap);
  }

  public Block() {
  }

  public Block(
    long blockId,
    String path,
    long numBytes,
    long genStamp,
    List<DatanodeInfo> nodes,
    long startOffset,
    String token)
  {
    this();
    this.blockId = blockId;
    setBlockIdIsSet(true);
    this.path = path;
    this.numBytes = numBytes;
    setNumBytesIsSet(true);
    this.genStamp = genStamp;
    setGenStampIsSet(true);
    this.nodes = nodes;
    this.startOffset = startOffset;
    setStartOffsetIsSet(true);
    this.token = token;
  }

  /**
   * Performs a deep copy on <i>other</i>.
   */
  public Block(Block other) {
    __isset_bitfield = other.__isset_bitfield;
    this.blockId = other.blockId;
    if (other.isSetPath()) {
      this.path = other.path;
    }
    this.numBytes = other.numBytes;
    this.genStamp = other.genStamp;
    if (other.isSetNodes()) {
      List<DatanodeInfo> __this__nodes = new ArrayList<DatanodeInfo>();
      for (DatanodeInfo other_element : other.nodes) {
        __this__nodes.add(new DatanodeInfo(other_element));
      }
      this.nodes = __this__nodes;
    }
    this.startOffset = other.startOffset;
    if (other.isSetToken()) {
      this.token = other.token;
    }
  }

  public Block deepCopy() {
    return new Block(this);
  }

  @Override
  public void clear() {
    setBlockIdIsSet(false);
    this.blockId = 0;
    this.path = null;
    setNumBytesIsSet(false);
    this.numBytes = 0;
    setGenStampIsSet(false);
    this.genStamp = 0;
    this.nodes = null;
    setStartOffsetIsSet(false);
    this.startOffset = 0;
    this.token = null;
  }

  /**
   * Block ID (unique among all blocks in a filesystem).
   */
  public long getBlockId() {
    return this.blockId;
  }

  /**
   * Block ID (unique among all blocks in a filesystem).
   */
  public Block setBlockId(long blockId) {
    this.blockId = blockId;
    setBlockIdIsSet(true);
    return this;
  }

  public void unsetBlockId() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __BLOCKID_ISSET_ID);
  }

  /** Returns true if field blockId is set (has been assigned a value) and false otherwise */
  public boolean isSetBlockId() {
    return EncodingUtils.testBit(__isset_bitfield, __BLOCKID_ISSET_ID);
  }

  public void setBlockIdIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __BLOCKID_ISSET_ID, value);
  }

  /**
   * Path of the file which this block belongs to.
   */
  public String getPath() {
    return this.path;
  }

  /**
   * Path of the file which this block belongs to.
   */
  public Block setPath(String path) {
    this.path = path;
    return this;
  }

  public void unsetPath() {
    this.path = null;
  }

  /** Returns true if field path is set (has been assigned a value) and false otherwise */
  public boolean isSetPath() {
    return this.path != null;
  }

  public void setPathIsSet(boolean value) {
    if (!value) {
      this.path = null;
    }
  }

  /**
   * Length of this block.
   */
  public long getNumBytes() {
    return this.numBytes;
  }

  /**
   * Length of this block.
   */
  public Block setNumBytes(long numBytes) {
    this.numBytes = numBytes;
    setNumBytesIsSet(true);
    return this;
  }

  public void unsetNumBytes() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __NUMBYTES_ISSET_ID);
  }

  /** Returns true if field numBytes is set (has been assigned a value) and false otherwise */
  public boolean isSetNumBytes() {
    return EncodingUtils.testBit(__isset_bitfield, __NUMBYTES_ISSET_ID);
  }

  public void setNumBytesIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __NUMBYTES_ISSET_ID, value);
  }

  /**
   * Generational stamp of this block.
   */
  public long getGenStamp() {
    return this.genStamp;
  }

  /**
   * Generational stamp of this block.
   */
  public Block setGenStamp(long genStamp) {
    this.genStamp = genStamp;
    setGenStampIsSet(true);
    return this;
  }

  public void unsetGenStamp() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __GENSTAMP_ISSET_ID);
  }

  /** Returns true if field genStamp is set (has been assigned a value) and false otherwise */
  public boolean isSetGenStamp() {
    return EncodingUtils.testBit(__isset_bitfield, __GENSTAMP_ISSET_ID);
  }

  public void setGenStampIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __GENSTAMP_ISSET_ID, value);
  }

  public int getNodesSize() {
    return (this.nodes == null) ? 0 : this.nodes.size();
  }

  public java.util.Iterator<DatanodeInfo> getNodesIterator() {
    return (this.nodes == null) ? null : this.nodes.iterator();
  }

  public void addToNodes(DatanodeInfo elem) {
    if (this.nodes == null) {
      this.nodes = new ArrayList<DatanodeInfo>();
    }
    this.nodes.add(elem);
  }

  /**
   * List of data nodes with copies  of this block.
   */
  public List<DatanodeInfo> getNodes() {
    return this.nodes;
  }

  /**
   * List of data nodes with copies  of this block.
   */
  public Block setNodes(List<DatanodeInfo> nodes) {
    this.nodes = nodes;
    return this;
  }

  public void unsetNodes() {
    this.nodes = null;
  }

  /** Returns true if field nodes is set (has been assigned a value) and false otherwise */
  public boolean isSetNodes() {
    return this.nodes != null;
  }

  public void setNodesIsSet(boolean value) {
    if (!value) {
      this.nodes = null;
    }
  }

  /**
   * Offset of the first byte of the block relative to the start of the file
   */
  public long getStartOffset() {
    return this.startOffset;
  }

  /**
   * Offset of the first byte of the block relative to the start of the file
   */
  public Block setStartOffset(long startOffset) {
    this.startOffset = startOffset;
    setStartOffsetIsSet(true);
    return this;
  }

  public void unsetStartOffset() {
    __isset_bitfield = EncodingUtils.clearBit(__isset_bitfield, __STARTOFFSET_ISSET_ID);
  }

  /** Returns true if field startOffset is set (has been assigned a value) and false otherwise */
  public boolean isSetStartOffset() {
    return EncodingUtils.testBit(__isset_bitfield, __STARTOFFSET_ISSET_ID);
  }

  public void setStartOffsetIsSet(boolean value) {
    __isset_bitfield = EncodingUtils.setBit(__isset_bitfield, __STARTOFFSET_ISSET_ID, value);
  }

  /**
   * The serialized token associated with this block.
   */
  public String getToken() {
    return this.token;
  }

  /**
   * The serialized token associated with this block.
   */
  public Block setToken(String token) {
    this.token = token;
    return this;
  }

  public void unsetToken() {
    this.token = null;
  }

  /** Returns true if field token is set (has been assigned a value) and false otherwise */
  public boolean isSetToken() {
    return this.token != null;
  }

  public void setTokenIsSet(boolean value) {
    if (!value) {
      this.token = null;
    }
  }

  public void setFieldValue(_Fields field, Object value) {
    switch (field) {
    case BLOCK_ID:
      if (value == null) {
        unsetBlockId();
      } else {
        setBlockId((Long)value);
      }
      break;

    case PATH:
      if (value == null) {
        unsetPath();
      } else {
        setPath((String)value);
      }
      break;

    case NUM_BYTES:
      if (value == null) {
        unsetNumBytes();
      } else {
        setNumBytes((Long)value);
      }
      break;

    case GEN_STAMP:
      if (value == null) {
        unsetGenStamp();
      } else {
        setGenStamp((Long)value);
      }
      break;

    case NODES:
      if (value == null) {
        unsetNodes();
      } else {
        setNodes((List<DatanodeInfo>)value);
      }
      break;

    case START_OFFSET:
      if (value == null) {
        unsetStartOffset();
      } else {
        setStartOffset((Long)value);
      }
      break;

    case TOKEN:
      if (value == null) {
        unsetToken();
      } else {
        setToken((String)value);
      }
      break;

    }
  }

  public Object getFieldValue(_Fields field) {
    switch (field) {
    case BLOCK_ID:
      return Long.valueOf(getBlockId());

    case PATH:
      return getPath();

    case NUM_BYTES:
      return Long.valueOf(getNumBytes());

    case GEN_STAMP:
      return Long.valueOf(getGenStamp());

    case NODES:
      return getNodes();

    case START_OFFSET:
      return Long.valueOf(getStartOffset());

    case TOKEN:
      return getToken();

    }
    throw new IllegalStateException();
  }

  /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
  public boolean isSet(_Fields field) {
    if (field == null) {
      throw new IllegalArgumentException();
    }

    switch (field) {
    case BLOCK_ID:
      return isSetBlockId();
    case PATH:
      return isSetPath();
    case NUM_BYTES:
      return isSetNumBytes();
    case GEN_STAMP:
      return isSetGenStamp();
    case NODES:
      return isSetNodes();
    case START_OFFSET:
      return isSetStartOffset();
    case TOKEN:
      return isSetToken();
    }
    throw new IllegalStateException();
  }

  @Override
  public boolean equals(Object that) {
    if (that == null)
      return false;
    if (that instanceof Block)
      return this.equals((Block)that);
    return false;
  }

  public boolean equals(Block that) {
    if (that == null)
      return false;

    boolean this_present_blockId = true;
    boolean that_present_blockId = true;
    if (this_present_blockId || that_present_blockId) {
      if (!(this_present_blockId && that_present_blockId))
        return false;
      if (this.blockId != that.blockId)
        return false;
    }

    boolean this_present_path = true && this.isSetPath();
    boolean that_present_path = true && that.isSetPath();
    if (this_present_path || that_present_path) {
      if (!(this_present_path && that_present_path))
        return false;
      if (!this.path.equals(that.path))
        return false;
    }

    boolean this_present_numBytes = true;
    boolean that_present_numBytes = true;
    if (this_present_numBytes || that_present_numBytes) {
      if (!(this_present_numBytes && that_present_numBytes))
        return false;
      if (this.numBytes != that.numBytes)
        return false;
    }

    boolean this_present_genStamp = true;
    boolean that_present_genStamp = true;
    if (this_present_genStamp || that_present_genStamp) {
      if (!(this_present_genStamp && that_present_genStamp))
        return false;
      if (this.genStamp != that.genStamp)
        return false;
    }

    boolean this_present_nodes = true && this.isSetNodes();
    boolean that_present_nodes = true && that.isSetNodes();
    if (this_present_nodes || that_present_nodes) {
      if (!(this_present_nodes && that_present_nodes))
        return false;
      if (!this.nodes.equals(that.nodes))
        return false;
    }

    boolean this_present_startOffset = true;
    boolean that_present_startOffset = true;
    if (this_present_startOffset || that_present_startOffset) {
      if (!(this_present_startOffset && that_present_startOffset))
        return false;
      if (this.startOffset != that.startOffset)
        return false;
    }

    boolean this_present_token = true && this.isSetToken();
    boolean that_present_token = true && that.isSetToken();
    if (this_present_token || that_present_token) {
      if (!(this_present_token && that_present_token))
        return false;
      if (!this.token.equals(that.token))
        return false;
    }

    return true;
  }

  @Override
  public int hashCode() {
    return 0;
  }

  public int compareTo(Block other) {
    if (!getClass().equals(other.getClass())) {
      return getClass().getName().compareTo(other.getClass().getName());
    }

    int lastComparison = 0;
    Block typedOther = (Block)other;

    lastComparison = Boolean.valueOf(isSetBlockId()).compareTo(typedOther.isSetBlockId());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetBlockId()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.blockId, typedOther.blockId);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetPath()).compareTo(typedOther.isSetPath());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetPath()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.path, typedOther.path);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetNumBytes()).compareTo(typedOther.isSetNumBytes());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetNumBytes()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.numBytes, typedOther.numBytes);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetGenStamp()).compareTo(typedOther.isSetGenStamp());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetGenStamp()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.genStamp, typedOther.genStamp);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetNodes()).compareTo(typedOther.isSetNodes());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetNodes()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nodes, typedOther.nodes);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetStartOffset()).compareTo(typedOther.isSetStartOffset());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetStartOffset()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.startOffset, typedOther.startOffset);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    lastComparison = Boolean.valueOf(isSetToken()).compareTo(typedOther.isSetToken());
    if (lastComparison != 0) {
      return lastComparison;
    }
    if (isSetToken()) {
      lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.token, typedOther.token);
      if (lastComparison != 0) {
        return lastComparison;
      }
    }
    return 0;
  }

  public _Fields fieldForId(int fieldId) {
    return _Fields.findByThriftId(fieldId);
  }

  public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
    schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
  }

  public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
    schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
  }

  @Override
  public String toString() {
    StringBuilder sb = new StringBuilder("Block(");
    boolean first = true;

    sb.append("blockId:");
    sb.append(this.blockId);
    first = false;
    if (!first) sb.append(", ");
    sb.append("path:");
    if (this.path == null) {
      sb.append("null");
    } else {
      sb.append(this.path);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("numBytes:");
    sb.append(this.numBytes);
    first = false;
    if (!first) sb.append(", ");
    sb.append("genStamp:");
    sb.append(this.genStamp);
    first = false;
    if (!first) sb.append(", ");
    sb.append("nodes:");
    if (this.nodes == null) {
      sb.append("null");
    } else {
      sb.append(this.nodes);
    }
    first = false;
    if (!first) sb.append(", ");
    sb.append("startOffset:");
    sb.append(this.startOffset);
    first = false;
    if (!first) sb.append(", ");
    sb.append("token:");
    if (this.token == null) {
      sb.append("null");
    } else {
      sb.append(this.token);
    }
    first = false;
    sb.append(")");
    return sb.toString();
  }

  public void validate() throws org.apache.thrift.TException {
    // check for required fields
    // check for sub-struct validity
  }

  private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
    try {
      write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
    try {
      // it doesn't seem like you should have to do this, but java serialization is wacky, and doesn't call the default constructor.
      __isset_bitfield = 0;
      read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
    } catch (org.apache.thrift.TException te) {
      throw new java.io.IOException(te);
    }
  }

  private static class BlockStandardSchemeFactory implements SchemeFactory {
    public BlockStandardScheme getScheme() {
      return new BlockStandardScheme();
    }
  }

  private static class BlockStandardScheme extends StandardScheme<Block> {

    public void read(org.apache.thrift.protocol.TProtocol iprot, Block struct) throws org.apache.thrift.TException {
      org.apache.thrift.protocol.TField schemeField;
      iprot.readStructBegin();
      while (true)
      {
        schemeField = iprot.readFieldBegin();
        if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
          break;
        }
        switch (schemeField.id) {
          case 1: // BLOCK_ID
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.blockId = iprot.readI64();
              struct.setBlockIdIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 2: // PATH
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.path = iprot.readString();
              struct.setPathIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 3: // NUM_BYTES
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.numBytes = iprot.readI64();
              struct.setNumBytesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 4: // GEN_STAMP
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.genStamp = iprot.readI64();
              struct.setGenStampIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 5: // NODES
            if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
              {
                org.apache.thrift.protocol.TList _list0 = iprot.readListBegin();
                struct.nodes = new ArrayList<DatanodeInfo>(_list0.size);
                for (int _i1 = 0; _i1 < _list0.size; ++_i1)
                {
                  DatanodeInfo _elem2; // required
                  _elem2 = new DatanodeInfo();
                  _elem2.read(iprot);
                  struct.nodes.add(_elem2);
                }
                iprot.readListEnd();
              }
              struct.setNodesIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 6: // START_OFFSET
            if (schemeField.type == org.apache.thrift.protocol.TType.I64) {
              struct.startOffset = iprot.readI64();
              struct.setStartOffsetIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          case 7: // TOKEN
            if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
              struct.token = iprot.readString();
              struct.setTokenIsSet(true);
            } else { 
              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
            }
            break;
          default:
            org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
        }
        iprot.readFieldEnd();
      }
      iprot.readStructEnd();

      // check for required fields of primitive type, which can't be checked in the validate method
      struct.validate();
    }

    public void write(org.apache.thrift.protocol.TProtocol oprot, Block struct) throws org.apache.thrift.TException {
      struct.validate();

      oprot.writeStructBegin(STRUCT_DESC);
      oprot.writeFieldBegin(BLOCK_ID_FIELD_DESC);
      oprot.writeI64(struct.blockId);
      oprot.writeFieldEnd();
      if (struct.path != null) {
        oprot.writeFieldBegin(PATH_FIELD_DESC);
        oprot.writeString(struct.path);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(NUM_BYTES_FIELD_DESC);
      oprot.writeI64(struct.numBytes);
      oprot.writeFieldEnd();
      oprot.writeFieldBegin(GEN_STAMP_FIELD_DESC);
      oprot.writeI64(struct.genStamp);
      oprot.writeFieldEnd();
      if (struct.nodes != null) {
        oprot.writeFieldBegin(NODES_FIELD_DESC);
        {
          oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.nodes.size()));
          for (DatanodeInfo _iter3 : struct.nodes)
          {
            _iter3.write(oprot);
          }
          oprot.writeListEnd();
        }
        oprot.writeFieldEnd();
      }
      oprot.writeFieldBegin(START_OFFSET_FIELD_DESC);
      oprot.writeI64(struct.startOffset);
      oprot.writeFieldEnd();
      if (struct.token != null) {
        oprot.writeFieldBegin(TOKEN_FIELD_DESC);
        oprot.writeString(struct.token);
        oprot.writeFieldEnd();
      }
      oprot.writeFieldStop();
      oprot.writeStructEnd();
    }

  }

  private static class BlockTupleSchemeFactory implements SchemeFactory {
    public BlockTupleScheme getScheme() {
      return new BlockTupleScheme();
    }
  }

  private static class BlockTupleScheme extends TupleScheme<Block> {

    @Override
    public void write(org.apache.thrift.protocol.TProtocol prot, Block struct) throws org.apache.thrift.TException {
      TTupleProtocol oprot = (TTupleProtocol) prot;
      BitSet optionals = new BitSet();
      if (struct.isSetBlockId()) {
        optionals.set(0);
      }
      if (struct.isSetPath()) {
        optionals.set(1);
      }
      if (struct.isSetNumBytes()) {
        optionals.set(2);
      }
      if (struct.isSetGenStamp()) {
        optionals.set(3);
      }
      if (struct.isSetNodes()) {
        optionals.set(4);
      }
      if (struct.isSetStartOffset()) {
        optionals.set(5);
      }
      if (struct.isSetToken()) {
        optionals.set(6);
      }
      oprot.writeBitSet(optionals, 7);
      if (struct.isSetBlockId()) {
        oprot.writeI64(struct.blockId);
      }
      if (struct.isSetPath()) {
        oprot.writeString(struct.path);
      }
      if (struct.isSetNumBytes()) {
        oprot.writeI64(struct.numBytes);
      }
      if (struct.isSetGenStamp()) {
        oprot.writeI64(struct.genStamp);
      }
      if (struct.isSetNodes()) {
        {
          oprot.writeI32(struct.nodes.size());
          for (DatanodeInfo _iter4 : struct.nodes)
          {
            _iter4.write(oprot);
          }
        }
      }
      if (struct.isSetStartOffset()) {
        oprot.writeI64(struct.startOffset);
      }
      if (struct.isSetToken()) {
        oprot.writeString(struct.token);
      }
    }

    @Override
    public void read(org.apache.thrift.protocol.TProtocol prot, Block struct) throws org.apache.thrift.TException {
      TTupleProtocol iprot = (TTupleProtocol) prot;
      BitSet incoming = iprot.readBitSet(7);
      if (incoming.get(0)) {
        struct.blockId = iprot.readI64();
        struct.setBlockIdIsSet(true);
      }
      if (incoming.get(1)) {
        struct.path = iprot.readString();
        struct.setPathIsSet(true);
      }
      if (incoming.get(2)) {
        struct.numBytes = iprot.readI64();
        struct.setNumBytesIsSet(true);
      }
      if (incoming.get(3)) {
        struct.genStamp = iprot.readI64();
        struct.setGenStampIsSet(true);
      }
      if (incoming.get(4)) {
        {
          org.apache.thrift.protocol.TList _list5 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
          struct.nodes = new ArrayList<DatanodeInfo>(_list5.size);
          for (int _i6 = 0; _i6 < _list5.size; ++_i6)
          {
            DatanodeInfo _elem7; // required
            _elem7 = new DatanodeInfo();
            _elem7.read(iprot);
            struct.nodes.add(_elem7);
          }
        }
        struct.setNodesIsSet(true);
      }
      if (incoming.get(5)) {
        struct.startOffset = iprot.readI64();
        struct.setStartOffsetIsSet(true);
      }
      if (incoming.get(6)) {
        struct.token = iprot.readString();
        struct.setTokenIsSet(true);
      }
    }
  }

}

