blob: 9396fd8e6bde2308bb2617302992dece5c7ea689 [file] [log] [blame]
<!--
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed
with this work for additional information regarding copyright
ownership. The ASF licenses this file to you under the Apache
License, Version 2.0 (the License); you may not use this file
except in compliance with the License. You may obtain a copy of
the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied. See the License for the specific language governing
permissions and limitations under the License.
Copyright 1999-2007 Rogue Wave Software, Inc.
-->
<HTML>
<HEAD>
<TITLE>Copies of the Stream Buffer</TITLE>
<LINK REL=StyleSheet HREF="../rw.css" TYPE="text/css" TITLE="Apache stdcxx Stylesheet"></HEAD>
<BODY BGCOLOR=#FFFFFF>
<A HREF="34-3.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="35.html"><IMG SRC="images/bnext.gif" WIDTH=25 HEIGHT=21 ALT="Next file" BORDER=O></A><DIV CLASS="DOCUMENTNAME"><B>Apache C++ Standard Library User's Guide</B></DIV>
<H2>34.4 Copies of the Stream Buffer</H2>
<A NAME="idx866"><!></A>
<A NAME="idx867"><!></A>
<P>The previous section showed how you can read the content of a file in its entirety by using the <SAMP>rdbuf()</SAMP> member function. Let us now explore a variation of that example. Imagine another file containing some sort of header information that needs to be analyzed before we start appending the file. Instead of writing the current file content to the standard output stream, we want to process the content before we start adding to it. The easiest way to put the entire file content into a memory location for further processing is by creating a string stream and inserting the file's stream buffer into the string stream:</P>
<UL><PRE>
std::fstream fil("/tmp/inout");
std::stringstream header_stream; //1
header_stream &lt;&lt; fil.rdbuf(); //2
// process the header, for example
std::string word;
header_stream &gt;&gt; word; //3
</PRE></UL>
<TABLE CELLPADDING="3">
<TR VALIGN="top"><TD><SAMP>//1</SAMP></TD><TD>The easiest way to put the entire file content into a memory location for further processing is by creating a string stream, and
<TR VALIGN="top"><TD><SAMP>//2</SAMP></TD><TD>Inserting the file's stream buffer into the string stream.
<TR VALIGN="top"><TD><SAMP>//3</SAMP></TD><TD>We now have the usual facilities of an input stream for reading and analyzing the header information; that is, <SAMP>operator&gt;&gt;()</SAMP>, <SAMP>read()</SAMP>, <SAMP>get()</SAMP>, and so on.
</TABLE>
<P>In cases where this procedure is insufficient, you should create a string that contains the header information and process the header by means of the string operations <SAMP>find()</SAMP>, <SAMP>compare()</SAMP>, etc.</P>
<UL><PRE>
std::fstream fil("/tmp/inout");
header_stream &lt;&lt; fil.rdbuf();
std::string header_string = header_stream.str();
// process the header, for example
std::string::size_type pos = header_string.rfind('.');
</PRE></UL>
<P>If the header contains binary data instead of text, even a string will probably not suffice. Here you would want to see the header as a plain byte sequence, that is, an ordinary <SAMP>char*</SAMP> buffer. But note that a code conversion might already have been performed, depending on the locale attached to the file stream. In cases where you want to process binary data, you must ensure that the attached locale has a non-converting code conversion facet:</P>
<UL><PRE>
std::fstream fil("/tmp/inout");
header_stream &lt;&lt; fil.rdbuf();
std::string header_string = header_stream.str();
const char* header_char_ptr = header_string.data();
// process the header, for example
int idx;
std::memcpy((char*) &amp;idx,header_char_ptr,sizeof(int));
</PRE></UL>
<P>A note on efficiency: if the header information is extensive, you must consider the number of copy operations performed in the previous example. <A HREF="34-4.html#Figure&nbsp;34">Figure&nbsp;34</A> shows how these copies are made:</P>
<A NAME="idx868"><!></A>
<H4><A NAME="Figure&nbsp;34">Figure&nbsp;34: Copies of the file content</A></H4>
<P><IMG SRC="images/iofig19.gif" WIDTH=564 HEIGHT=463></P>
<P>The content of the file is copied into the string stream's buffer when the pointer obtained through <SAMP>rdbuf()</SAMP> is inserted to the string stream. A second copy is created when the string stream's function <SAMP>str()</SAMP> is called. The call to the string's function <SAMP>data()</SAMP> does not create yet another copy, but returns a pointer to the string's internal data.</P>
<BR>
<HR>
<A HREF="34-3.html"><IMG SRC="images/bprev.gif" WIDTH=20 HEIGHT=21 ALT="Previous file" BORDER=O></A><A HREF="noframes.html"><IMG SRC="images/btop.gif" WIDTH=56 HEIGHT=21 ALT="Top of Document" BORDER=O></A><A HREF="booktoc.html"><IMG SRC="images/btoc.gif" WIDTH=56 HEIGHT=21 ALT="Contents" BORDER=O></A><A HREF="tindex.html"><IMG SRC="images/bindex.gif" WIDTH=56 HEIGHT=21 ALT="Index page" BORDER=O></A><A HREF="35.html"><IMG SRC="images/bnext.gif" WIDTH=20 HEIGHT=21 ALT="Next file" BORDER=O></A>
<!-- Google Analytics tracking code -->
<script src="http://www.google-analytics.com/urchin.js" type="text/javascript">
</script>
<script type="text/javascript">
_uacct = "UA-1775151-1";
urchinTracker();
</script>
<!-- end of Google Analytics tracking code -->
</BODY>
</HTML>