source: box/trunk/lib/common/BufferedStream.cpp @ 2728

Revision 2728, 5.3 KB checked in by chris, 21 months ago (diff)

Implement write buffering on directories.

  • Property svn:eol-style set to native
Line 
1// --------------------------------------------------------------------------
2//
3// File
4//              Name:    BufferedStream.cpp
5//              Purpose: Buffering read-only wrapper around IOStreams
6//              Created: 2007/01/16
7//
8// --------------------------------------------------------------------------
9
10#include "Box.h"
11#include "BufferedStream.h"
12#include "CommonException.h"
13
14#include <string.h>
15
16#include "MemLeakFindOn.h"
17
18// --------------------------------------------------------------------------
19//
20// Function
21//              Name:    BufferedStream::BufferedStream(const char *, int, int)
22//              Purpose: Constructor, set up buffer
23//              Created: 2007/01/16
24//
25// --------------------------------------------------------------------------
26BufferedStream::BufferedStream(IOStream& rSource)
27: mrSource(rSource), mBufferSize(0), mBufferPosition(0)
28{ }
29
30
31// --------------------------------------------------------------------------
32//
33// Function
34//              Name:    BufferedStream::Read(void *, int)
35//              Purpose: Reads bytes from the file
36//              Created: 2007/01/16
37//
38// --------------------------------------------------------------------------
39int BufferedStream::Read(void *pBuffer, int NBytes, int Timeout)
40{
41        if (mBufferSize == mBufferPosition)
42        {
43                // buffer is empty, fill it.
44
45                int numBytesRead = mrSource.Read(mBuffer, sizeof(mBuffer), 
46                        Timeout);
47
48                if (numBytesRead < 0)
49                {
50                        return numBytesRead;
51                }
52
53                mBufferSize = numBytesRead;
54        }
55
56        int sizeToReturn = mBufferSize - mBufferPosition;
57
58        if (sizeToReturn > NBytes)
59        {
60                sizeToReturn = NBytes;
61        }
62
63        memcpy(pBuffer, mBuffer + mBufferPosition, sizeToReturn);
64        mBufferPosition += sizeToReturn;
65
66        if (mBufferPosition == mBufferSize)
67        {
68                // clear out the buffer
69                mBufferSize = 0;
70                mBufferPosition = 0;
71        }
72
73        return sizeToReturn;
74}
75
76
77// --------------------------------------------------------------------------
78//
79// Function
80//              Name:    BufferedStream::BytesLeftToRead()
81//              Purpose: Returns number of bytes to read (may not be most efficient function ever)
82//              Created: 2007/01/16
83//
84// --------------------------------------------------------------------------
85IOStream::pos_type BufferedStream::BytesLeftToRead()
86{
87        return mrSource.BytesLeftToRead() + mBufferSize - mBufferPosition;
88}
89
90
91// --------------------------------------------------------------------------
92//
93// Function
94//              Name:    BufferedStream::Write(void *, int)
95//              Purpose: Writes bytes to the underlying stream (not supported)
96//              Created: 2003/07/31
97//
98// --------------------------------------------------------------------------
99void BufferedStream::Write(const void *pBuffer, int NBytes)
100{
101        THROW_EXCEPTION(CommonException, NotSupported);
102}
103
104
105// --------------------------------------------------------------------------
106//
107// Function
108//              Name:    BufferedStream::GetPosition()
109//              Purpose: Get position in stream
110//              Created: 2003/08/21
111//
112// --------------------------------------------------------------------------
113IOStream::pos_type BufferedStream::GetPosition() const
114{
115        return mrSource.GetPosition() - mBufferSize + mBufferPosition;
116}
117
118
119// --------------------------------------------------------------------------
120//
121// Function
122//              Name:    BufferedStream::Seek(pos_type, int)
123//              Purpose: Seeks within file, as lseek, invalidate buffer
124//              Created: 2003/07/31
125//
126// --------------------------------------------------------------------------
127void BufferedStream::Seek(IOStream::pos_type Offset, int SeekType)
128{
129        switch (SeekType)
130        {
131                case SeekType_Absolute:
132                {
133                        // just go there
134                        mrSource.Seek(Offset, SeekType);
135                }
136                break;
137
138                case SeekType_Relative:
139                {
140                        // Actual underlying file position is
141                        // (mBufferSize - mBufferPosition) ahead of us.
142                        // Need to subtract that amount from the seek
143                        // to seek forward that much less, putting the
144                        // real pointer in the right place.
145                        mrSource.Seek(Offset - mBufferSize + mBufferPosition, 
146                                SeekType);
147                }
148                break;
149
150                case SeekType_End:
151                {
152                        // Actual underlying file position is
153                        // (mBufferSize - mBufferPosition) ahead of us.
154                        // Need to add that amount to the seek
155                        // to seek backwards that much more, putting the
156                        // real pointer in the right place.
157                        mrSource.Seek(Offset + mBufferSize - mBufferPosition, 
158                                SeekType);
159                }
160        }
161
162        // always clear the buffer for now (may be slightly wasteful)
163        mBufferSize = 0;
164        mBufferPosition = 0;
165}
166
167
168// --------------------------------------------------------------------------
169//
170// Function
171//              Name:    BufferedStream::Close()
172//              Purpose: Closes the underlying stream (not needed)
173//              Created: 2003/07/31
174//
175// --------------------------------------------------------------------------
176void BufferedStream::Close()
177{
178        THROW_EXCEPTION(CommonException, NotSupported);
179}
180
181
182// --------------------------------------------------------------------------
183//
184// Function
185//              Name:    BufferedStream::StreamDataLeft()
186//              Purpose: Any data left to write?
187//              Created: 2003/08/02
188//
189// --------------------------------------------------------------------------
190bool BufferedStream::StreamDataLeft()
191{
192        return mrSource.StreamDataLeft();
193}
194
195// --------------------------------------------------------------------------
196//
197// Function
198//              Name:    BufferedStream::StreamClosed()
199//              Purpose: Is the stream closed?
200//              Created: 2003/08/02
201//
202// --------------------------------------------------------------------------
203bool BufferedStream::StreamClosed()
204{
205        return mrSource.StreamClosed();
206}
207
Note: See TracBrowser for help on using the repository browser.