132
|
1 /*******************************************************************************
|
|
2
|
|
3 copyright: Copyright (c) 2007 Kris Bell. All rights reserved
|
|
4
|
|
5 license: BSD style: $(LICENSE)
|
|
6
|
|
7 version: Initial release: Oct 2007
|
|
8
|
|
9 author: Kris
|
|
10
|
|
11 *******************************************************************************/
|
|
12
|
|
13 module tango.io.stream.DigestStream;
|
|
14
|
|
15 private import tango.io.Conduit;
|
|
16
|
|
17 private import tango.io.digest.Digest;
|
|
18
|
|
19 /*******************************************************************************
|
|
20
|
|
21 Inject a digest filter into an input stream, updating the digest
|
|
22 as information flows through it
|
|
23
|
|
24 *******************************************************************************/
|
|
25
|
|
26 class DigestInput : InputFilter
|
|
27 {
|
|
28 private Digest filter;
|
|
29
|
|
30 /***********************************************************************
|
|
31
|
|
32 Accepts any input stream, and any digest derivation
|
|
33
|
|
34 ***********************************************************************/
|
|
35
|
|
36 this (InputStream stream, Digest digest)
|
|
37 {
|
|
38 super (stream);
|
|
39 filter = digest;
|
|
40 }
|
|
41
|
|
42 /***********************************************************************
|
|
43
|
|
44 Read from conduit into a target array. The provided dst
|
|
45 will be populated with content from the conduit.
|
|
46
|
|
47 Returns the number of bytes read, which may be less than
|
|
48 requested in dst (or IOStream.Eof for end-of-flow)
|
|
49
|
|
50 ***********************************************************************/
|
|
51
|
|
52 final override uint read (void[] dst)
|
|
53 {
|
|
54 auto len = host.read (dst);
|
|
55 if (len != Eof)
|
|
56 filter.update (dst [0 .. len]);
|
|
57 return len;
|
|
58 }
|
|
59
|
|
60 /********************************************************************
|
|
61
|
|
62 Return the Digest instance we were created with. Use this
|
|
63 to access the resultant binary or hex digest value
|
|
64
|
|
65 *********************************************************************/
|
|
66
|
|
67 final Digest digest()
|
|
68 {
|
|
69 return filter;
|
|
70 }
|
|
71 }
|
|
72
|
|
73
|
|
74 /*******************************************************************************
|
|
75
|
|
76 Inject a digest filter into an output stream, updating the digest
|
|
77 as information flows through it. Here's an example where we calculate
|
|
78 an MD5 digest as a side-effect of copying a file:
|
|
79 ---
|
|
80 auto output = new DigestOutput(new FileOutput("output"), new Md5);
|
|
81 output.copy (new FileInput("input"));
|
|
82
|
|
83 Stdout.formatln ("hex digest: {}", output.digest.hexDigest);
|
|
84 ---
|
|
85
|
|
86 *******************************************************************************/
|
|
87
|
|
88 class DigestOutput : OutputFilter
|
|
89 {
|
|
90 private Digest filter;
|
|
91
|
|
92 /***********************************************************************
|
|
93
|
|
94 Accepts any output stream, and any digest derivation
|
|
95
|
|
96 ***********************************************************************/
|
|
97
|
|
98 this (OutputStream stream, Digest digest)
|
|
99 {
|
|
100 super (stream);
|
|
101 filter = digest;
|
|
102 }
|
|
103
|
|
104 /***********************************************************************
|
|
105
|
|
106 Write to conduit from a source array. The provided src
|
|
107 content will be written to the conduit.
|
|
108
|
|
109 Returns the number of bytes written from src, which may
|
|
110 be less than the quantity provided
|
|
111
|
|
112 ***********************************************************************/
|
|
113
|
|
114 final override uint write (void[] src)
|
|
115 {
|
|
116 auto len = host.write (src);
|
|
117 if (len != Eof)
|
|
118 filter.update (src[0 .. len]);
|
|
119 return len;
|
|
120 }
|
|
121
|
|
122 /********************************************************************
|
|
123
|
|
124 Return the Digest instance we were created with. Use this
|
|
125 to access the resultant binary or hex digest value
|
|
126
|
|
127 *********************************************************************/
|
|
128
|
|
129 final Digest digest()
|
|
130 {
|
|
131 return filter;
|
|
132 }
|
|
133 }
|
|
134
|
|
135
|
|
136 /*******************************************************************************
|
|
137
|
|
138 *******************************************************************************/
|
|
139
|
|
140 debug (DigestStream)
|
|
141 {
|
|
142 import tango.io.Stdout;
|
|
143 import tango.io.GrowBuffer;
|
|
144 import tango.io.digest.Md5;
|
|
145 import tango.io.stream.FileStream;
|
|
146
|
|
147 void main()
|
|
148 {
|
|
149 auto output = new DigestOutput(new GrowBuffer, new Md5);
|
|
150 output.copy (new FileInput("digeststream.d"));
|
|
151
|
|
152 Stdout.formatln ("hex digest:{}", output.digest.hexDigest);
|
|
153 }
|
|
154 }
|