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 the ZeroCopyInputStream and ZeroCopyOutputStream 00036 // interfaces, which represent abstract I/O streams to and from which 00037 // protocol buffers can be read and written. For a few simple 00038 // implementations of these interfaces, see zero_copy_stream_impl.h. 00039 // 00040 // These interfaces are different from classic I/O streams in that they 00041 // try to minimize the amount of data copying that needs to be done. 00042 // To accomplish this, responsibility for allocating buffers is moved to 00043 // the stream object, rather than being the responsibility of the caller. 00044 // So, the stream can return a buffer which actually points directly into 00045 // the final data structure where the bytes are to be stored, and the caller 00046 // can interact directly with that buffer, eliminating an intermediate copy 00047 // operation. 00048 // 00049 // As an example, consider the common case in which you are reading bytes 00050 // from an array that is already in memory (or perhaps an mmap()ed file). 00051 // With classic I/O streams, you would do something like: 00052 // char buffer[BUFFER_SIZE]; 00053 // input->Read(buffer, BUFFER_SIZE); 00054 // DoSomething(buffer, BUFFER_SIZE); 00055 // Then, the stream basically just calls memcpy() to copy the data from 00056 // the array into your buffer. With a ZeroCopyInputStream, you would do 00057 // this instead: 00058 // const void* buffer; 00059 // int size; 00060 // input->Next(&buffer, &size); 00061 // DoSomething(buffer, size); 00062 // Here, no copy is performed. The input stream returns a pointer directly 00063 // into the backing array, and the caller ends up reading directly from it. 00064 // 00065 // If you want to be able to read the old-fashion way, you can create 00066 // a CodedInputStream or CodedOutputStream wrapping these objects and use 00067 // their ReadRaw()/WriteRaw() methods. These will, of course, add a copy 00068 // step, but Coded*Stream will handle buffering so at least it will be 00069 // reasonably efficient. 00070 // 00071 // ZeroCopyInputStream example: 00072 // // Read in a file and print its contents to stdout. 00073 // int fd = open("myfile", O_RDONLY); 00074 // ZeroCopyInputStream* input = new FileInputStream(fd); 00075 // 00076 // const void* buffer; 00077 // int size; 00078 // while (input->Next(&buffer, &size)) { 00079 // cout.write(buffer, size); 00080 // } 00081 // 00082 // delete input; 00083 // close(fd); 00084 // 00085 // ZeroCopyOutputStream example: 00086 // // Copy the contents of "infile" to "outfile", using plain read() for 00087 // // "infile" but a ZeroCopyOutputStream for "outfile". 00088 // int infd = open("infile", O_RDONLY); 00089 // int outfd = open("outfile", O_WRONLY); 00090 // ZeroCopyOutputStream* output = new FileOutputStream(outfd); 00091 // 00092 // void* buffer; 00093 // int size; 00094 // while (output->Next(&buffer, &size)) { 00095 // int bytes = read(infd, buffer, size); 00096 // if (bytes < size) { 00097 // // Reached EOF. 00098 // output->BackUp(size - bytes); 00099 // break; 00100 // } 00101 // } 00102 // 00103 // delete output; 00104 // close(infd); 00105 // close(outfd); 00106 00107 #ifndef GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ 00108 #define GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__ 00109 00110 #include <string> 00111 #include <google/protobuf/stubs/common.h> 00112 00113 namespace google { 00114 00115 namespace protobuf { 00116 namespace io { 00117 00118 // Defined in this file. 00119 class ZeroCopyInputStream; 00120 class ZeroCopyOutputStream; 00121 00122 // Abstract interface similar to an input stream but designed to minimize 00123 // copying. 00124 class LIBPROTOBUF_EXPORT ZeroCopyInputStream { 00125 public: 00126 inline ZeroCopyInputStream() {} 00127 virtual ~ZeroCopyInputStream(); 00128 00129 // Obtains a chunk of data from the stream. 00130 // 00131 // Preconditions: 00132 // * "size" and "data" are not NULL. 00133 // 00134 // Postconditions: 00135 // * If the returned value is false, there is no more data to return or 00136 // an error occurred. All errors are permanent. 00137 // * Otherwise, "size" points to the actual number of bytes read and "data" 00138 // points to a pointer to a buffer containing these bytes. 00139 // * Ownership of this buffer remains with the stream, and the buffer 00140 // remains valid only until some other method of the stream is called 00141 // or the stream is destroyed. 00142 // * It is legal for the returned buffer to have zero size, as long 00143 // as repeatedly calling Next() eventually yields a buffer with non-zero 00144 // size. 00145 virtual bool Next(const void** data, int* size) = 0; 00146 00147 // Backs up a number of bytes, so that the next call to Next() returns 00148 // data again that was already returned by the last call to Next(). This 00149 // is useful when writing procedures that are only supposed to read up 00150 // to a certain point in the input, then return. If Next() returns a 00151 // buffer that goes beyond what you wanted to read, you can use BackUp() 00152 // to return to the point where you intended to finish. 00153 // 00154 // Preconditions: 00155 // * The last method called must have been Next(). 00156 // * count must be less than or equal to the size of the last buffer 00157 // returned by Next(). 00158 // 00159 // Postconditions: 00160 // * The last "count" bytes of the last buffer returned by Next() will be 00161 // pushed back into the stream. Subsequent calls to Next() will return 00162 // the same data again before producing new data. 00163 virtual void BackUp(int count) = 0; 00164 00165 // Skips a number of bytes. Returns false if the end of the stream is 00166 // reached or some input error occurred. In the end-of-stream case, the 00167 // stream is advanced to the end of the stream (so ByteCount() will return 00168 // the total size of the stream). 00169 virtual bool Skip(int count) = 0; 00170 00171 // Returns the total number of bytes read since this object was created. 00172 virtual int64 ByteCount() const = 0; 00173 00174 00175 private: 00176 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyInputStream); 00177 }; 00178 00179 // Abstract interface similar to an output stream but designed to minimize 00180 // copying. 00181 class LIBPROTOBUF_EXPORT ZeroCopyOutputStream { 00182 public: 00183 inline ZeroCopyOutputStream() {} 00184 virtual ~ZeroCopyOutputStream(); 00185 00186 // Obtains a buffer into which data can be written. Any data written 00187 // into this buffer will eventually (maybe instantly, maybe later on) 00188 // be written to the output. 00189 // 00190 // Preconditions: 00191 // * "size" and "data" are not NULL. 00192 // 00193 // Postconditions: 00194 // * If the returned value is false, an error occurred. All errors are 00195 // permanent. 00196 // * Otherwise, "size" points to the actual number of bytes in the buffer 00197 // and "data" points to the buffer. 00198 // * Ownership of this buffer remains with the stream, and the buffer 00199 // remains valid only until some other method of the stream is called 00200 // or the stream is destroyed. 00201 // * Any data which the caller stores in this buffer will eventually be 00202 // written to the output (unless BackUp() is called). 00203 // * It is legal for the returned buffer to have zero size, as long 00204 // as repeatedly calling Next() eventually yields a buffer with non-zero 00205 // size. 00206 virtual bool Next(void** data, int* size) = 0; 00207 00208 // Backs up a number of bytes, so that the end of the last buffer returned 00209 // by Next() is not actually written. This is needed when you finish 00210 // writing all the data you want to write, but the last buffer was bigger 00211 // than you needed. You don't want to write a bunch of garbage after the 00212 // end of your data, so you use BackUp() to back up. 00213 // 00214 // Preconditions: 00215 // * The last method called must have been Next(). 00216 // * count must be less than or equal to the size of the last buffer 00217 // returned by Next(). 00218 // * The caller must not have written anything to the last "count" bytes 00219 // of that buffer. 00220 // 00221 // Postconditions: 00222 // * The last "count" bytes of the last buffer returned by Next() will be 00223 // ignored. 00224 virtual void BackUp(int count) = 0; 00225 00226 // Returns the total number of bytes written since this object was created. 00227 virtual int64 ByteCount() const = 0; 00228 00229 00230 private: 00231 GOOGLE_DISALLOW_EVIL_CONSTRUCTORS(ZeroCopyOutputStream); 00232 }; 00233 00234 } // namespace io 00235 } // namespace protobuf 00236 00237 } // namespace google 00238 #endif // GOOGLE_PROTOBUF_IO_ZERO_COPY_STREAM_H__