1 /* 2 * Created on Mar 7, 2012 3 * Created by Paul Gardner 4 * 5 * Copyright (C) Azureus Software, Inc, All Rights Reserved. 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License 9 * as published by the Free Software Foundation; either version 2 10 * of the License, or (at your option) any later version. 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 18 */ 19 20 21 package com.aelitis.azureus.core.peermanager.messaging.azureus; 22 23 import java.nio.ByteBuffer; 24 import java.util.HashMap; 25 import java.util.Map; 26 27 import org.gudy.azureus2.core3.util.BDecoder; 28 import org.gudy.azureus2.core3.util.BEncoder; 29 import org.gudy.azureus2.core3.util.DirectByteBuffer; 30 31 import com.aelitis.azureus.core.peermanager.messaging.Message; 32 import com.aelitis.azureus.core.peermanager.messaging.MessageException; 33 import com.aelitis.azureus.core.peermanager.messaging.MessagingUtil; 34 35 public class 36 AZMetaData 37 implements AZMessage, AZUTMetaData 38 { 39 private final byte version; 40 private DirectByteBuffer buffer = null; 41 42 private int msg_type; 43 private int piece; 44 private DirectByteBuffer metadata; 45 private int total_size; 46 47 public AZMetaData( int _piece, byte _version )48 AZMetaData( 49 int _piece, 50 byte _version ) 51 { 52 msg_type = MSG_TYPE_REQUEST; 53 piece = _piece; 54 version = _version; 55 } 56 57 public AZMetaData( int _piece, ByteBuffer _data, int _total_size, byte _version )58 AZMetaData( 59 int _piece, 60 ByteBuffer _data, 61 int _total_size, 62 byte _version ) 63 { 64 msg_type = _data==null?MSG_TYPE_REJECT:MSG_TYPE_DATA; 65 piece = _piece; 66 total_size = _total_size; 67 version = _version; 68 69 if ( _data != null ){ 70 71 metadata = new DirectByteBuffer( _data ); 72 } 73 } 74 75 public AZMetaData( Map map, DirectByteBuffer data, byte _version )76 AZMetaData( 77 Map map, 78 DirectByteBuffer data, 79 byte _version ) 80 { 81 if ( map != null ){ 82 83 msg_type = ((Long)map.get( "msg_type" )).intValue(); 84 piece = ((Long)map.get( "piece" )).intValue(); 85 } 86 87 metadata = data; 88 version = _version; 89 } 90 91 public String getID()92 getID() 93 { 94 return( ID_AZ_METADATA ); 95 } 96 97 public byte[] getIDBytes()98 getIDBytes() 99 { 100 return( ID_AZ_METADATA_BYTES ); 101 } 102 103 public String getFeatureID()104 getFeatureID() 105 { 106 return( AZ_FEATURE_ID ); 107 } 108 109 public int getFeatureSubID()110 getFeatureSubID() 111 { 112 return SUBID_ID_AZ_METADATA; 113 } 114 115 public int getType()116 getType() 117 { 118 return Message.TYPE_PROTOCOL_PAYLOAD; 119 } 120 121 public byte getVersion()122 getVersion() 123 { 124 return( version ); 125 }; 126 127 public String getDescription()128 getDescription() 129 { 130 return( getID() + " piece #" + piece + ", mt=" + msg_type ); 131 } 132 133 public int getMessageType()134 getMessageType() 135 { 136 return( msg_type ); 137 } 138 139 public int getPiece()140 getPiece() 141 { 142 return( piece ); 143 } 144 145 public DirectByteBuffer getMetadata()146 getMetadata() 147 { 148 return( metadata ); 149 } 150 151 public void setMetadata( DirectByteBuffer b )152 setMetadata( 153 DirectByteBuffer b ) 154 { 155 metadata = b; 156 } 157 158 public DirectByteBuffer[] getData()159 getData() 160 { 161 if ( buffer == null ){ 162 163 Map payload_map = new HashMap(); 164 165 payload_map.put( "msg_type", new Long( msg_type )); 166 payload_map.put( "piece", new Long(piece)); 167 168 if ( total_size > 0 ){ 169 170 payload_map.put( "total_size", total_size ); 171 } 172 173 buffer = MessagingUtil.convertPayloadToBencodedByteStream(payload_map, DirectByteBuffer.AL_MSG_AZ_METADATA ); 174 } 175 176 if ( msg_type == MSG_TYPE_DATA ){ 177 178 return new DirectByteBuffer[]{ buffer, metadata }; 179 180 }else{ 181 182 return new DirectByteBuffer[]{ buffer }; 183 } 184 } 185 186 187 188 public Message deserialize( DirectByteBuffer data, byte version )189 deserialize( 190 DirectByteBuffer data, 191 byte version ) 192 193 throws MessageException 194 { 195 int pos = data.position( DirectByteBuffer.SS_MSG ); 196 197 byte[] dict_bytes = new byte[ Math.min( 128, data.remaining( DirectByteBuffer.SS_MSG )) ]; 198 199 data.get( DirectByteBuffer.SS_MSG, dict_bytes ); 200 201 try{ 202 Map root = BDecoder.decode( dict_bytes ); 203 204 data.position( DirectByteBuffer.SS_MSG, pos + BEncoder.encode( root ).length ); 205 206 return( new AZMetaData( root, data, version )); 207 208 }catch( Throwable e ){ 209 210 e.printStackTrace(); 211 212 throw( new MessageException( "decode failed", e )); 213 } 214 } 215 216 217 public void destroy()218 destroy() 219 { 220 if ( buffer != null ){ 221 222 buffer.returnToPool(); 223 } 224 225 if ( metadata != null ){ 226 227 metadata.returnToPool(); 228 } 229 } 230 }