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 module hunt.proton.codec.CompositeWritableBuffer; 12 13 import hunt.io.ByteBuffer; 14 15 import hunt.proton.codec.ReadableBuffer; 16 import hunt.io.BufferUtils; 17 import hunt.proton.codec.WritableBuffer; 18 import hunt.Float; 19 import hunt.Double; 20 import hunt.String; 21 22 class CompositeWritableBuffer : WritableBuffer 23 { 24 private WritableBuffer _first; 25 private WritableBuffer _second; 26 27 this(WritableBuffer first, WritableBuffer second) 28 { 29 _first = first; 30 _second = second; 31 } 32 33 override 34 public void put(byte b) 35 { 36 (_first.hasRemaining() ? _first : _second).put(b); 37 } 38 39 override 40 public void putFloat(float f) 41 { 42 putInt(Float.floatToRawIntBits(f)); 43 } 44 45 override 46 public void putDouble(double d) 47 { 48 putLong(Double.doubleToRawLongBits(d)); 49 } 50 51 override 52 public void putShort(short s) 53 { 54 int remaining = _first.remaining(); 55 if(remaining >= 2) 56 { 57 _first.putShort(s); 58 } 59 else if(remaining ==0 ) 60 { 61 _second.putShort(s); 62 } 63 else 64 { 65 ByteBuffer wrap = BufferUtils.toBuffer(new byte[2]); 66 wrap.putShort(s); 67 wrap.flip(); 68 put(wrap); 69 } 70 } 71 72 override 73 public void putInt(int i) 74 { 75 int remaining = _first.remaining(); 76 if(remaining >= 4) 77 { 78 _first.putInt(i); 79 } 80 else if(remaining ==0 ) 81 { 82 _second.putInt(i); 83 } 84 else 85 { 86 ByteBuffer wrap = BufferUtils.toBuffer(new byte[4]); 87 wrap.putInt(i); 88 wrap.flip(); 89 put(wrap); 90 } 91 } 92 93 override 94 public void putLong(long l) 95 { 96 int remaining = _first.remaining(); 97 if(remaining >= 8) 98 { 99 _first.putLong(l); 100 } 101 else if(remaining ==0 ) 102 { 103 _second.putLong(l); 104 } 105 else 106 { 107 ByteBuffer wrap = BufferUtils.toBuffer(new byte[8]); 108 wrap.putLong(l); 109 wrap.flip(); 110 put(wrap); 111 } 112 } 113 114 override 115 public bool hasRemaining() 116 { 117 return _first.hasRemaining() || _second.hasRemaining(); 118 } 119 120 override 121 public int remaining() 122 { 123 return _first.remaining()+_second.remaining(); 124 } 125 126 override 127 public int position() 128 { 129 return _first.position()+_second.position(); 130 } 131 132 override 133 public int limit() 134 { 135 return _first.limit() + _second.limit(); 136 } 137 138 override 139 public void position(int position) 140 { 141 int first_limit = _first.limit(); 142 if( position <= first_limit ) 143 { 144 _first.position(position); 145 _second.position(0); 146 } 147 else 148 { 149 _first.position(first_limit); 150 _second.position(position - first_limit); 151 } 152 } 153 154 override 155 public void put(byte[] src, int offset, int length) 156 { 157 int firstRemaining = _first.remaining(); 158 if(firstRemaining > 0) 159 { 160 if(firstRemaining >= length) 161 { 162 _first.put(src, offset, length); 163 return; 164 } 165 else 166 { 167 _first.put(src,offset, firstRemaining); 168 } 169 } 170 _second.put(src, offset+firstRemaining, length-firstRemaining); 171 } 172 173 override 174 public void put(ByteBuffer payload) 175 { 176 int firstRemaining = _first.remaining(); 177 if(firstRemaining > 0) 178 { 179 if(firstRemaining >= payload.remaining()) 180 { 181 _first.put(payload); 182 return; 183 } 184 else 185 { 186 int limit = payload.limit(); 187 payload.limit(payload.position()+firstRemaining); 188 _first.put(payload); 189 payload.limit(limit); 190 } 191 } 192 _second.put(payload); 193 } 194 195 //override 196 //public String toString() 197 //{ 198 // return _first.toString() ~ " ~ "+_second.toString(); 199 //} 200 201 override 202 public void put(ReadableBuffer payload) { 203 int firstRemaining = _first.remaining(); 204 if(firstRemaining > 0) 205 { 206 if(firstRemaining >= payload.remaining()) 207 { 208 _first.put(payload); 209 return; 210 } 211 else 212 { 213 int limit = payload.limit(); 214 payload.limit(payload.position()+firstRemaining); 215 _first.put(payload); 216 payload.limit(limit); 217 } 218 } 219 _second.put(payload); 220 } 221 222 public void put(String value) 223 { 224 if (_first.hasRemaining()) 225 { 226 byte[] utf8Bytes = value.getBytes(); 227 put(utf8Bytes, 0, cast(int)utf8Bytes.length); 228 } 229 else 230 { 231 _second.put(cast(string)value.getBytes()); 232 } 233 } 234 }