Pyrogenesis  13997
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
stream.cpp
Go to the documentation of this file.
1 /* Copyright (c) 2010 Wildfire Games
2  *
3  * Permission is hereby granted, free of charge, to any person obtaining
4  * a copy of this software and associated documentation files (the
5  * "Software"), to deal in the Software without restriction, including
6  * without limitation the rights to use, copy, modify, merge, publish,
7  * distribute, sublicense, and/or sell copies of the Software, and to
8  * permit persons to whom the Software is furnished to do so, subject to
9  * the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included
12  * in all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17  * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
18  * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
19  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
20  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21  */
22 
23 #include "precompiled.h"
25 
28 #include "lib/file/archive/codec.h"
29 //#include "lib/timer.h"
30 
31 //TIMER_ADD_CLIENT(tc_stream);
32 
33 
35 {
36  Reset();
37 }
38 
40 {
41  m_buffer = 0;
42  m_size = 0;
43  m_capacity = 0;
44 }
45 
46 void OutputBufferManager::SetBuffer(u8* buffer, size_t size)
47 {
48  ENSURE(IsAllowableBuffer(buffer, size));
49 
50  m_buffer = buffer;
51  m_size = size;
52 }
53 
55 {
56  // notes:
57  // - this implementation allows reusing previous buffers if they
58  // are big enough, which reduces the number of allocations.
59  // - no further attempts to reduce allocations (e.g. by doubling
60  // the current size) are made; this strategy is enough.
61  // - Pool etc. cannot be used because files may be huge (larger
62  // than the address space of 32-bit systems).
63 
64  // no buffer or the previous one wasn't big enough: reallocate
65  if(!m_mem || m_capacity < size)
66  {
67  AllocateAligned(m_mem, size);
68  m_capacity = size;
69  }
70 
71  SetBuffer(m_mem.get(), size);
72 }
73 
74 bool OutputBufferManager::IsAllowableBuffer(u8* buffer, size_t size)
75 {
76  // none yet established
77  if(m_buffer == 0 && m_size == 0)
78  return true;
79 
80  // same as last time (happens with temp buffers)
81  if(m_buffer == buffer && m_size == size)
82  return true;
83 
84  // located after the last buffer (note: not necessarily after
85  // the entire buffer; a lack of input can cause the output buffer
86  // to only partially be used before the next call.)
87  if((unsigned)(buffer - m_buffer) <= m_size)
88  return true;
89 
90  return false;
91 }
92 
93 
94 //-----------------------------------------------------------------------------
95 
96 
97 Stream::Stream(const PICodec& codec)
98  : m_codec(codec)
99  , m_inConsumed(0), m_outProduced(0)
100 {
101 }
102 
103 
104 void Stream::AllocateOutputBuffer(size_t outSizeMax)
105 {
107 }
108 
109 
110 void Stream::SetOutputBuffer(u8* out, size_t outSize)
111 {
112  m_outputBufferManager.SetBuffer(out, outSize);
113 }
114 
115 
116 Status Stream::Feed(const u8* in, size_t inSize)
117 {
118  if(m_outProduced == m_outputBufferManager.Size()) // output buffer full; must not call Process
119  return INFO::ALL_COMPLETE;
120 
121  size_t inConsumed, outProduced;
123  const size_t outSize = m_outputBufferManager.Size() - m_outProduced;
124  RETURN_STATUS_IF_ERR(m_codec->Process(in, inSize, out, outSize, inConsumed, outProduced));
125 
126  m_inConsumed += inConsumed;
127  m_outProduced += outProduced;
128  return INFO::OK;
129 }
130 
131 
133 {
134  size_t outProduced;
135  RETURN_STATUS_IF_ERR(m_codec->Finish(m_checksum, outProduced));
136  m_outProduced += outProduced;
137  return INFO::OK;
138 }
#define u8
Definition: types.h:39
size_t m_inConsumed
Definition: stream.h:108
const Status OK
Definition: status.h:386
void SetBuffer(u8 *buffer, size_t size)
Definition: stream.cpp:46
void SetOutputBuffer(u8 *out, size_t outSize)
Definition: stream.cpp:110
static void out(const wchar_t *fmt,...)
Definition: wdbg_sym.cpp:419
bool IsAllowableBuffer(u8 *buffer, size_t size)
Definition: stream.cpp:74
const Status ALL_COMPLETE
Definition: status.h:400
size_t Size() const
Definition: stream.h:59
size_t m_capacity
Definition: stream.h:74
#define ENSURE(expr)
ensure the expression &lt;expr&gt; evaluates to non-zero.
Definition: debug.h:282
Status Finish()
Definition: stream.cpp:132
shared_ptr< u8 > m_mem
Definition: stream.h:70
i64 Status
Error handling system.
Definition: status.h:171
OutputBufferManager m_outputBufferManager
Definition: stream.h:106
Stream(const PICodec &codec)
Definition: stream.cpp:97
PICodec m_codec
Definition: stream.h:105
static Status AllocateAligned(shared_ptr< T > &p, size_t size, size_t alignment=cacheLineSize)
Definition: shared_ptr.h:66
u32 m_checksum
Definition: stream.h:110
size_t m_outProduced
Definition: stream.h:109
shared_ptr< ICodec > PICodec
Definition: codec.h:92
u8 * Buffer() const
Definition: stream.h:54
void AllocateOutputBuffer(size_t outSizeMax)
Definition: stream.cpp:104
Status Feed(const u8 *in, size_t inSize)
&#39;feed&#39; the codec with a data block.
Definition: stream.cpp:116
void AllocateBuffer(size_t size)
allocate a new output buffer.
Definition: stream.cpp:54
#define RETURN_STATUS_IF_ERR(expression)
Definition: status.h:276