Stroika Library
3.0d24
Help-Home
Loading...
Searching...
No Matches
ToSeekableInputStream.h
Go to the documentation of this file.
1
/*
2
* Copyright(c) Sophist Solutions, Inc. 1990-2026. All rights reserved
3
*/
4
#ifndef _Stroika_Foundation_Streams_ToSeekableInputStream_h_
5
#define _Stroika_Foundation_Streams_ToSeekableInputStream_h_ 1
6
7
#include "Stroika/Foundation/StroikaPreComp.h"
8
9
#include "
Stroika/Foundation/Streams/InputStream.h
"
10
#include "
Stroika/Foundation/Traversal/Iterable.h
"
11
12
/**
13
* \file
14
*
15
* \note Code-Status: <a href="Code-Status.md#Beta">Beta</a>
16
*/
17
18
namespace
Stroika::Foundation::Streams::ToSeekableInputStream {
19
20
using
InputStream::Ptr;
21
22
/**
23
* Not all input streams are seekable, but throwing a little memory at it, its easy to assure they are all
24
* seekable.
25
*
26
* That's what this utility does: maps the given input stream into a functionally identical one, except possibly
27
* adding seekability.
28
*
29
* If the argument stream is already seekable, New () just returns its argument (so perhaps a misnomer but I thought better
30
* to follow factory pattern).
31
*
32
* \par Example Usage
33
* \code
34
* InputStream::Ptr<byte> in = ToSeekableInputStream::New<byte> (existingInputStream);
35
* \endcode
36
*
37
* A socket is the canonical stream you might want this for: there is nowhere to seek back TO, because
38
* the bytes are gone once read (IO::Network::SocketStream::IsSeekable () returns false; so does
39
* InputStreamFromStdIStream constructed eNotSeekable - over cin, say). Wrapping one lets code that
40
* must read the same input twice do so:
41
*
42
* \par Example Usage
43
* \code
44
* SocketStream::Ptr socketStream = SocketStream::New (connectionSocket);
45
* InputStream::Ptr<byte> in = ToSeekableInputStream::New<byte> (socketStream);
46
* DoFirstPass (in);
47
* in.Seek (0); // legal only because of the wrapper; socketStream itself cannot seek
48
* DoSecondPass (in); // sees the very same bytes again, served out of the cache
49
* \endcode
50
*
51
* That two-pass shape is why this exists: see Providers::LibXML2::Provider::SAXParse (), which needs
52
* it when asked to both validate against a schema and report parse events, because that reads twice.
53
*
54
* \note this helper does not require it be given the input stream at SeekOffset 0, but for pretty obvious reasons
55
* it cannot produce a stream that permits seeking backwards from where it starts. This is checked via assertions.
56
*
57
* \note this helper may be problematic with very large streams, as it caches the stream in memory as it reads, and would
58
* eventually run out.
59
*
60
* \note ELEMENT_TYPE is effectively limited to byte today: SeekRead () accumulates into the cache through
61
* a hardcoded 'byte' buffer, so instantiating this for any other element type will not compile.
62
*/
63
template
<
typename
ELEMENT_TYPE>
64
auto
New (
const
Ptr<ELEMENT_TYPE>& in) -> Ptr<ELEMENT_TYPE>;
65
66
}
67
68
/*
69
********************************************************************************
70
***************************** Implementation Details ***************************
71
********************************************************************************
72
*/
73
#include "ToSeekableInputStream.inl"
74
75
#endif
/*_Stroika_Foundation_Streams_ToSeekableInputStream_h_*/
InputStream.h
Iterable.h
Library
Sources
Stroika
Foundation
Streams
ToSeekableInputStream.h
Generated by
1.9.8