1 /* 2 * hunt-proton: AMQP Protocol library for D programming language. 3 * 4 * Copyright (C) 2018-2019 HuntLabs 5 * 6 * Website: https://www.huntlabs.net/ 7 * 8 * Licensed under the Apache-2.0 License. 9 * 10 */ 11 12 module hunt.proton.amqp.Binary; 13 14 import hunt.io.ByteBuffer; 15 import hunt.collection.Collection; 16 import hunt.proton.codec.ReadableBuffer; 17 import hunt.io.BufferUtils; 18 19 class Binary 20 { 21 private byte[] _data; 22 private int _offset; 23 private int _length; 24 private int _hashCode; 25 26 this( byte[] data) 27 { 28 this(data, 0, cast(int)(data.length)); 29 } 30 31 this( byte[] data, int offset,int length) 32 { 33 _data = data; 34 _offset = offset; 35 _length = length; 36 } 37 38 public ByteBuffer asByteBuffer() 39 { 40 return BufferUtils.toBuffer(_data,_offset,_length); 41 } 42 43 //override 44 //public int hashCode() 45 //{ 46 // int hc = _hashCode; 47 // if(hc == 0) 48 // { 49 // for (int i = 0; i < _length; i++) 50 // { 51 // hc = 31*hc + (0xFF & _data[_offset + i]); 52 // } 53 // _hashCode = hc; 54 // } 55 // return hc; 56 //} 57 58 override 59 public size_t toHash() @trusted nothrow 60 { 61 int hc = _hashCode; 62 if(hc == 0) 63 { 64 for (int i = 0; i < _length; i++) 65 { 66 hc = 31*hc + (0xFF & _data[_offset + i]); 67 } 68 _hashCode = hc; 69 } 70 return cast(size_t)hc; 71 } 72 73 override bool opEquals(Object o) 74 { 75 if (this is o) 76 { 77 return true; 78 } 79 80 if (o is null || cast(Binary)o is null) 81 { 82 return false; 83 } 84 85 Binary buf = cast(Binary) o; 86 int size = _length; 87 if (size != buf.getLength()) 88 { 89 return false; 90 } 91 92 byte[] myData = _data; 93 byte[] theirData = buf.getArray(); 94 int myOffset = _offset; 95 int theirOffset = buf.getArrayOffset(); 96 int myLimit = myOffset + size; 97 98 while(myOffset < myLimit) 99 { 100 if (myData[myOffset++] != theirData[theirOffset++]) 101 { 102 return false; 103 } 104 } 105 106 return true; 107 } 108 109 public int getArrayOffset() 110 { 111 return _offset; 112 } 113 114 public byte[] getArray() 115 { 116 return _data; 117 } 118 119 public int getLength() 120 { 121 return _length; 122 } 123 124 125 public static Binary combine(Collection!Binary binaries) 126 { 127 if(binaries.size() == 1) 128 { 129 return binaries.iterator().front(); 130 } 131 132 byte[] data ; 133 foreach(Binary binary ; binaries) 134 { 135 data ~= binary.getArray()[binary.getArrayOffset() .. $]; 136 } 137 return new Binary(data); 138 } 139 140 public Binary subBinary(int offset,int length) 141 { 142 return new Binary(_data, _offset+offset, length); 143 } 144 145 public static Binary create(ReadableBuffer buffer) 146 { 147 if (buffer is null) 148 { 149 return null; 150 } 151 else if (!buffer.hasArray()) 152 { 153 byte[] data = new byte [buffer.remaining()]; 154 ReadableBuffer dup = buffer.duplicate(); 155 dup.get(data); 156 return new Binary(data); 157 } 158 else 159 { 160 return new Binary(buffer.array(), buffer.arrayOffset() + buffer.position(), buffer.remaining()); 161 } 162 } 163 164 public static Binary create(ByteBuffer buffer) 165 { 166 if (buffer is null) 167 { 168 return null; 169 } 170 if (buffer.isDirect() || buffer.isReadOnly()) 171 { 172 byte[] data = new byte [buffer.remaining()]; 173 ByteBuffer dup = buffer.duplicate(); 174 dup.get(data); 175 return new Binary(data); 176 } 177 else 178 { 179 return new Binary(buffer.array(), buffer.arrayOffset()+buffer.position(), buffer.remaining()); 180 } 181 } 182 183 public static Binary copy(Binary source) 184 { 185 if (source is null) 186 { 187 return null; 188 } 189 else 190 { 191 byte[] data ; 192 // System.arraycopy(source.getArray(), source.getArrayOffset(), data, 0, source.getLength()); 193 data ~= source.getArray()[source.getArrayOffset() .. $]; 194 return new Binary(data); 195 } 196 } 197 }