Package freenet.client.async

Source Code of freenet.client.async.BinaryBlob

package freenet.client.async;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.EOFException;
import java.io.IOException;

import com.onionnetworks.util.FileUtil;

import freenet.keys.Key;
import freenet.keys.KeyBlock;
import freenet.keys.KeyVerifyException;

public abstract class BinaryBlob {

  public static final long BINARY_BLOB_MAGIC = 0x6d58249f72d67ed9L;
  public static final short BINARY_BLOB_OVERALL_VERSION = 0;
  public static void writeBinaryBlobHeader(DataOutputStream binaryBlobStream) throws IOException {
    binaryBlobStream.writeLong(BinaryBlob.BINARY_BLOB_MAGIC);
    binaryBlobStream.writeShort(BinaryBlob.BINARY_BLOB_OVERALL_VERSION);
  }
  public static void writeKey(DataOutputStream binaryBlobStream, KeyBlock block, Key key) throws IOException {
    byte[] keyData = key.getKeyBytes();
    byte[] headers = block.getRawHeaders();
    byte[] data = block.getRawData();
    byte[] pubkey = block.getPubkeyBytes();
    writeBlobHeader(binaryBlobStream, BLOB_BLOCK, BLOB_BLOCK_VERSION,
        9+keyData.length+headers.length+data.length+(pubkey==null?0:pubkey.length));
    binaryBlobStream.writeShort(block.getKey().getType());
    binaryBlobStream.writeByte(keyData.length);
    binaryBlobStream.writeShort(headers.length);
    binaryBlobStream.writeShort(data.length);
    binaryBlobStream.writeShort(pubkey == null ? 0 : pubkey.length);
    binaryBlobStream.write(keyData);
    binaryBlobStream.write(headers);
    binaryBlobStream.write(data);
    if(pubkey != null)
      binaryBlobStream.write(pubkey);
  }
  static final short BLOB_BLOCK = 1;
  static final short BLOB_BLOCK_VERSION = 0;
  static final short BLOB_END = 2;
  static final short BLOB_END_VERSION = 0;
  public static final String MIME_TYPE = "application/x-freenet-binary-blob";
  static void writeBlobHeader(DataOutputStream binaryBlobStream, short type, short version, int length) throws IOException {
    binaryBlobStream.writeInt(length);
    binaryBlobStream.writeShort(type);
    binaryBlobStream.writeShort(version);
  }
  public static void writeEndBlob(DataOutputStream binaryBlobStream) throws IOException {
    writeBlobHeader(binaryBlobStream, BinaryBlob.BLOB_END, BinaryBlob.BLOB_END_VERSION, 0);
  }

  public static void readBinaryBlob(DataInputStream dis, BlockSet blocks, boolean tolerant) throws IOException, BinaryBlobFormatException {
    long magic = dis.readLong();
    if(magic != BinaryBlob.BINARY_BLOB_MAGIC)
      throw new BinaryBlobFormatException("Bad magic");
    short version = dis.readShort();
    if(version != BinaryBlob.BINARY_BLOB_OVERALL_VERSION)
      throw new BinaryBlobFormatException("Unknown overall version");
   
    while(true) {
      long blobLength;
      try {
        blobLength = dis.readInt() & 0xFFFFFFFFL;
      } catch (EOFException e) {
        // End of file
        dis.close();
        break;
      }
      short blobType = dis.readShort();
      short blobVer = dis.readShort();
     
      if(blobType == BinaryBlob.BLOB_END) {
        dis.close();
        break;
      } else if(blobType == BinaryBlob.BLOB_BLOCK) {
        if(blobVer != BinaryBlob.BLOB_BLOCK_VERSION)
          // Even if tolerant, if we can't read a blob there probably isn't much we can do.
          throw new BinaryBlobFormatException("Unknown block blob version");
        if(blobLength < 9)
          throw new BinaryBlobFormatException("Block blob too short");
        short keyType = dis.readShort();
        int keyLen = dis.readUnsignedByte();
        int headersLen = dis.readUnsignedShort();
        int dataLen = dis.readUnsignedShort();
        int pubkeyLen = dis.readUnsignedShort();
        int total = 9 + keyLen + headersLen + dataLen + pubkeyLen;
        if(blobLength != total)
          throw new BinaryBlobFormatException("Binary blob not same length as data: blobLength="+blobLength+" total="+total);
        byte[] keyBytes = new byte[keyLen];
        byte[] headersBytes = new byte[headersLen];
        byte[] dataBytes = new byte[dataLen];
        byte[] pubkeyBytes = new byte[pubkeyLen];
        dis.readFully(keyBytes);
        dis.readFully(headersBytes);
        dis.readFully(dataBytes);
        dis.readFully(pubkeyBytes);
        KeyBlock block;
        try {
          block = Key.createBlock(keyType, keyBytes, headersBytes, dataBytes, pubkeyBytes);
        } catch (KeyVerifyException e) {
          throw new BinaryBlobFormatException("Invalid key: "+e.getMessage(), e);
        }
       
        blocks.add(block);
       
      } else {
        if(tolerant) {
          FileUtil.skipFully(dis, blobLength);
        } else {
          throw new BinaryBlobFormatException("Unknown blob type: "+blobType);
        }
      }
    }

  }
}
TOP

Related Classes of freenet.client.async.BinaryBlob

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.