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