1 /* 2 * Hunt - A refined core 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.stream.BufferedOutputStream; 13 14 import hunt.stream.Common; 15 import hunt.Exceptions; 16 import hunt.logging; 17 18 /** 19 * 20 */ 21 class BufferedOutputStream : OutputStream { 22 protected OutputStream output; 23 protected int bufferSize; 24 /** 25 * The internal buffer where data is stored. 26 */ 27 protected byte[] buf; 28 29 /** 30 * The number of valid bytes in the buffer. This value is always 31 * in the range {@code 0} through {@code buf.length}; elements 32 * {@code buf[0]} through {@code buf[count-1]} contain valid 33 * byte data. 34 */ 35 protected int count; 36 37 this(OutputStream output, int bufferSize = 1024) { 38 this.output = output; 39 if (bufferSize > 1024) { 40 this.bufferSize = bufferSize; 41 this.buf = new byte[bufferSize]; 42 } else { 43 this.bufferSize = 1024; 44 this.buf = new byte[1024]; 45 } 46 } 47 48 alias write = OutputStream.write; 49 50 override 51 void write(int b) { 52 if (count >= buf.length) { 53 flush(); 54 } 55 buf[count++] = cast(byte) b; 56 } 57 58 override 59 void write(byte[] array, int offset, int length) { 60 if (array is null || array.length == 0 || length <= 0) { 61 return; 62 } 63 64 if (offset < 0) { 65 throw new IllegalArgumentException("the offset is less than 0"); 66 } 67 68 if (length >= buf.length) { 69 flush(); 70 output.write(array, offset, length); 71 return; 72 } 73 if (length > buf.length - count) { 74 flush(); 75 } 76 buf[count .. count+length] = array[offset .. offset+length]; 77 count += length; 78 79 // version(HUNT_DEBUG) 80 // tracef("%(%02X %)", buf[0 .. count]); 81 } 82 83 override 84 void flush() { 85 debug(HUNT_DEBUG_MORE) { 86 tracef("remaining: %d bytes", count); 87 } 88 if (count > 0) { 89 output.write(buf, 0, count); 90 count = 0; 91 buf = new byte[bufferSize]; 92 } 93 } 94 95 override 96 void close() { 97 flush(); 98 output.close(); 99 } 100 }