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 }