BWAPI
|
00001 // Protocol Buffers - Google's data interchange format 00002 // Copyright 2008 Google Inc. All rights reserved. 00003 // http://code.google.com/p/protobuf/ 00004 // 00005 // Redistribution and use in source and binary forms, with or without 00006 // modification, are permitted provided that the following conditions are 00007 // met: 00008 // 00009 // * Redistributions of source code must retain the above copyright 00010 // notice, this list of conditions and the following disclaimer. 00011 // * Redistributions in binary form must reproduce the above 00012 // copyright notice, this list of conditions and the following disclaimer 00013 // in the documentation and/or other materials provided with the 00014 // distribution. 00015 // * Neither the name of Google Inc. nor the names of its 00016 // contributors may be used to endorse or promote products derived from 00017 // this software without specific prior written permission. 00018 // 00019 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00020 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00021 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 00022 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 00023 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 00024 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 00025 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 00026 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 00027 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 00028 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 00029 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 00030 00031 // Author: kenton@google.com (Kenton Varda) 00032 // Based on original Protocol Buffers design by 00033 // Sanjay Ghemawat, Jeff Dean, and others. 00034 // 00035 // This file contains common implementations of the interfaces defined in 00036 // zero_copy_stream.h which are only included in the full (non-lite) 00037 // protobuf library. These implementations include Unix file descriptors 00038 // and C++ iostreams. See also: zero_copy_stream_impl_lite.h 00039 00040 #ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ 00041 #define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__ 00042 00043 #include <string> 00044 #include <iosfwd> 00045 #include <google/protobuf/io/zero_copy_stream.h> 00046 #include <google/protobuf/io/zero_copy_stream_impl_lite.h> 00047 #include <google/protobuf/stubs/common.h> 00048 00049 00050 namespace google { 00051 namespace protobuf { 00052 namespace io { 00053 00054 00055 // =================================================================== 00056 00057 // A ZeroCopyInputStream which reads from a file descriptor. 00058 // 00059 // FileInputStream is preferred over using an ifstream with IstreamInputStream. 00060 // The latter will introduce an extra layer of buffering, harming performance. 00061 // Also, it's conceivable that FileInputStream could someday be enhanced 00062 // to use zero-copy file descriptors on OSs which support them. 00063 class LIBPROTOBUF_EXPORT FileInputStream : public ZeroCopyInputStream { 00064 public: 00065 // Creates a stream that reads from the given Unix file descriptor. 00066 // If a block_size is given, it specifies the number of bytes that 00067 // should be read and returned with each call to Next(). Otherwise, 00068 // a reasonable default is used. 00069 explicit FileInputStream(int file_descriptor, int block_size = -1); 00070 ~FileInputStream(); 00071 00072 // Flushes any buffers and closes the underlying file. Returns false if 00073 // an error occurs during the process; use GetErrno() to examine the error. 00074 // Even if an error occurs, the file descriptor is closed when this returns. 00075 bool Close(); 00076 00077 // By default, the file descriptor is not closed when the stream is 00078 // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: 00079 // This leaves no way for the caller to detect if close() fails. If 00080 // detecting close() errors is important to you, you should arrange 00081 // to close the descriptor yourself. 00082 void SetCloseOnDelete(bool value) { copying_input_.SetCloseOnDelete(value); } 00083 00084 // If an I/O error has occurred on this file descriptor, this is the 00085 // errno from that error. Otherwise, this is zero. Once an error 00086 // occurs, the stream is broken and all subsequent operations will 00087 // fail. 00088 int GetErrno() { return copying_input_.GetErrno(); } 00089 00090 // implements ZeroCopyInputStream ---------------------------------- 00091 bool Next(const void** data, int* size); 00092 void BackUp(int count); 00093 bool Skip(int count); 00094 int64 ByteCount() const; 00095 00096 private: 00097 class LIBPROTOBUF_EXPORT CopyingFileInputStream : public CopyingInputStream { 00098 public: 00099 CopyingFileInputStream(int file_descriptor); 00100 ~CopyingFileInputStream(); 00101 00102 bool Close(); 00103 void SetCloseOnDelete(bool value) { close_on_delete_ = value; } 00104 int GetErrno() { return errno_; } 00105 00106 // implements CopyingInputStream --------------------------------- 00107 int Read(void* buffer, int size); 00108 int Skip(int count); 00109 00110 private: 00111 // The file descriptor. 00112 const int file_; 00113 bool close_on_delete_; 00114 bool is_closed_; 00115 00116 // The errno of the I/O error, if one has occurred. Otherwise, zero. 00117 int errno_; 00118 00119 // Did we try to seek once and fail? If so, we assume this file descriptor 00120 // doesn't support seeking and won't try again. 00121 bool previous_seek_failed_; 00122 00123 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileInputStream); 00124 }; 00125 00126 CopyingFileInputStream copying_input_; 00127 CopyingInputStreamAdaptor impl_; 00128 00129 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileInputStream); 00130 }; 00131 00132 // =================================================================== 00133 00134 // A ZeroCopyOutputStream which writes to a file descriptor. 00135 // 00136 // FileOutputStream is preferred over using an ofstream with 00137 // OstreamOutputStream. The latter will introduce an extra layer of buffering, 00138 // harming performance. Also, it's conceivable that FileOutputStream could 00139 // someday be enhanced to use zero-copy file descriptors on OSs which 00140 // support them. 00141 class LIBPROTOBUF_EXPORT FileOutputStream : public ZeroCopyOutputStream { 00142 public: 00143 // Creates a stream that writes to the given Unix file descriptor. 00144 // If a block_size is given, it specifies the size of the buffers 00145 // that should be returned by Next(). Otherwise, a reasonable default 00146 // is used. 00147 explicit FileOutputStream(int file_descriptor, int block_size = -1); 00148 ~FileOutputStream(); 00149 00150 // Flushes any buffers and closes the underlying file. Returns false if 00151 // an error occurs during the process; use GetErrno() to examine the error. 00152 // Even if an error occurs, the file descriptor is closed when this returns. 00153 bool Close(); 00154 00155 // Flushes FileOutputStream's buffers but does not close the 00156 // underlying file. No special measures are taken to ensure that 00157 // underlying operating system file object is synchronized to disk. 00158 bool Flush(); 00159 00160 // By default, the file descriptor is not closed when the stream is 00161 // destroyed. Call SetCloseOnDelete(true) to change that. WARNING: 00162 // This leaves no way for the caller to detect if close() fails. If 00163 // detecting close() errors is important to you, you should arrange 00164 // to close the descriptor yourself. 00165 void SetCloseOnDelete(bool value) { copying_output_.SetCloseOnDelete(value); } 00166 00167 // If an I/O error has occurred on this file descriptor, this is the 00168 // errno from that error. Otherwise, this is zero. Once an error 00169 // occurs, the stream is broken and all subsequent operations will 00170 // fail. 00171 int GetErrno() { return copying_output_.GetErrno(); } 00172 00173 // implements ZeroCopyOutputStream --------------------------------- 00174 bool Next(void** data, int* size); 00175 void BackUp(int count); 00176 int64 ByteCount() const; 00177 00178 private: 00179 class LIBPROTOBUF_EXPORT CopyingFileOutputStream : public CopyingOutputStream { 00180 public: 00181 CopyingFileOutputStream(int file_descriptor); 00182 ~CopyingFileOutputStream(); 00183 00184 bool Close(); 00185 void SetCloseOnDelete(bool value) { close_on_delete_ = value; } 00186 int GetErrno() { return errno_; } 00187 00188 // implements CopyingOutputStream -------------------------------- 00189 bool Write(const void* buffer, int size); 00190 00191 private: 00192 // The file descriptor. 00193 const int file_; 00194 bool close_on_delete_; 00195 bool is_closed_; 00196 00197 // The errno of the I/O error, if one has occurred. Otherwise, zero. 00198 int errno_; 00199 00200 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingFileOutputStream); 00201 }; 00202 00203 CopyingFileOutputStream copying_output_; 00204 CopyingOutputStreamAdaptor impl_; 00205 00206 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(FileOutputStream); 00207 }; 00208 00209 // =================================================================== 00210 00211 // A ZeroCopyInputStream which reads from a C++ istream. 00212 // 00213 // Note that for reading files (or anything represented by a file descriptor), 00214 // FileInputStream is more efficient. 00215 class LIBPROTOBUF_EXPORT IstreamInputStream : public ZeroCopyInputStream { 00216 public: 00217 // Creates a stream that reads from the given C++ istream. 00218 // If a block_size is given, it specifies the number of bytes that 00219 // should be read and returned with each call to Next(). Otherwise, 00220 // a reasonable default is used. 00221 explicit IstreamInputStream(istream* stream, int block_size = -1); 00222 ~IstreamInputStream(); 00223 00224 // implements ZeroCopyInputStream ---------------------------------- 00225 bool Next(const void** data, int* size); 00226 void BackUp(int count); 00227 bool Skip(int count); 00228 int64 ByteCount() const; 00229 00230 private: 00231 class LIBPROTOBUF_EXPORT CopyingIstreamInputStream : public CopyingInputStream { 00232 public: 00233 CopyingIstreamInputStream(istream* input); 00234 ~CopyingIstreamInputStream(); 00235 00236 // implements CopyingInputStream --------------------------------- 00237 int Read(void* buffer, int size); 00238 // (We use the default implementation of Skip().) 00239 00240 private: 00241 // The stream. 00242 istream* input_; 00243 00244 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingIstreamInputStream); 00245 }; 00246 00247 CopyingIstreamInputStream copying_input_; 00248 CopyingInputStreamAdaptor impl_; 00249 00250 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(IstreamInputStream); 00251 }; 00252 00253 // =================================================================== 00254 00255 // A ZeroCopyOutputStream which writes to a C++ ostream. 00256 // 00257 // Note that for writing files (or anything represented by a file descriptor), 00258 // FileOutputStream is more efficient. 00259 class LIBPROTOBUF_EXPORT OstreamOutputStream : public ZeroCopyOutputStream { 00260 public: 00261 // Creates a stream that writes to the given C++ ostream. 00262 // If a block_size is given, it specifies the size of the buffers 00263 // that should be returned by Next(). Otherwise, a reasonable default 00264 // is used. 00265 explicit OstreamOutputStream(ostream* stream, int block_size = -1); 00266 ~OstreamOutputStream(); 00267 00268 // implements ZeroCopyOutputStream --------------------------------- 00269 bool Next(void** data, int* size); 00270 void BackUp(int count); 00271 int64 ByteCount() const; 00272 00273 private: 00274 class LIBPROTOBUF_EXPORT CopyingOstreamOutputStream : public CopyingOutputStream { 00275 public: 00276 CopyingOstreamOutputStream(ostream* output); 00277 ~CopyingOstreamOutputStream(); 00278 00279 // implements CopyingOutputStream -------------------------------- 00280 bool Write(const void* buffer, int size); 00281 00282 private: 00283 // The stream. 00284 ostream* output_; 00285 00286 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(CopyingOstreamOutputStream); 00287 }; 00288 00289 CopyingOstreamOutputStream copying_output_; 00290 CopyingOutputStreamAdaptor impl_; 00291 00292 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(OstreamOutputStream); 00293 }; 00294 00295 // =================================================================== 00296 00297 // A ZeroCopyInputStream which reads from several other streams in sequence. 00298 // ConcatenatingInputStream is unable to distinguish between end-of-stream 00299 // and read errors in the underlying streams, so it assumes any errors mean 00300 // end-of-stream. So, if the underlying streams fail for any other reason, 00301 // ConcatenatingInputStream may do odd things. It is suggested that you do 00302 // not use ConcatenatingInputStream on streams that might produce read errors 00303 // other than end-of-stream. 00304 class LIBPROTOBUF_EXPORT ConcatenatingInputStream : public ZeroCopyInputStream { 00305 public: 00306 // All streams passed in as well as the array itself must remain valid 00307 // until the ConcatenatingInputStream is destroyed. 00308 ConcatenatingInputStream(ZeroCopyInputStream* const streams[], int count); 00309 ~ConcatenatingInputStream(); 00310 00311 // implements ZeroCopyInputStream ---------------------------------- 00312 bool Next(const void** data, int* size); 00313 void BackUp(int count); 00314 bool Skip(int count); 00315 int64 ByteCount() const; 00316 00317 00318 private: 00319 // As streams are retired, streams_ is incremented and count_ is 00320 // decremented. 00321 ZeroCopyInputStream* const* streams_; 00322 int stream_count_; 00323 int64 bytes_retired_; // Bytes read from previous streams. 00324 00325 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ConcatenatingInputStream); 00326 }; 00327 00328 // =================================================================== 00329 00330 // A ZeroCopyInputStream which wraps some other stream and limits it to 00331 // a particular byte count. 00332 class LIBPROTOBUF_EXPORT LimitingInputStream : public ZeroCopyInputStream { 00333 public: 00334 LimitingInputStream(ZeroCopyInputStream* input, int64 limit); 00335 ~LimitingInputStream(); 00336 00337 // implements ZeroCopyInputStream ---------------------------------- 00338 bool Next(const void** data, int* size); 00339 void BackUp(int count); 00340 bool Skip(int count); 00341 int64 ByteCount() const; 00342 00343 00344 private: 00345 ZeroCopyInputStream* input_; 00346 int64 limit_; // Decreases as we go, becomes negative if we overshoot. 00347 00348 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(LimitingInputStream); 00349 }; 00350 00351 // =================================================================== 00352 00353 } // namespace io 00354 } // namespace protobuf 00355 00356 } // namespace google 00357 #endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_IMPL_H__