Google APIs Client Library for C++
|
00001 /* 00002 * \copyright Copyright 2013 Google Inc. All Rights Reserved. 00003 * \license @{ 00004 * 00005 * Licensed under the Apache License, Version 2.0 (the "License"); 00006 * you may not use this file except in compliance with the License. 00007 * You may obtain a copy of the License at 00008 * 00009 * http://www.apache.org/licenses/LICENSE-2.0 00010 * 00011 * Unless required by applicable law or agreed to in writing, software 00012 * distributed under the License is distributed on an "AS IS" BASIS, 00013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00014 * See the License for the specific language governing permissions and 00015 * limitations under the License. 00016 * 00017 * @} 00018 */ 00019 00020 // Author: ewiseblatt@google.com (Eric Wiseblatt) 00021 /* 00022 * @defgroup DataLayerCodec Data Layer - Data Encoder/Decoders 00023 * 00024 * The raw data encoders/decoders are components in the data layer that are 00025 * responsible for transforming data. Typical examples are encoding, 00026 * encryption and compression. Transformations can be performed on entire 00027 * byte sequences or on individual chunks. 00028 */ 00029 00030 #ifndef APISERVING_CLIENTS_CPP_DATA_CODEC_H_ 00031 #define APISERVING_CLIENTS_CPP_DATA_CODEC_H_ 00032 00033 #include <string> 00034 using std::string; 00035 00036 #include "googleapis/client/data/data_reader.h" 00037 #include "googleapis/base/callback.h" 00038 #include "googleapis/base/macros.h" 00039 #include "googleapis/strings/stringpiece.h" 00040 #include "googleapis/util/status.h" 00041 namespace googleapis { 00042 00043 namespace client { 00044 00045 /* 00046 * Provides an interface for encoding and decoding data. 00047 * @ingroup DataLayerCodec 00048 * 00049 * This is a pure abstract class. It needs to be subclassed to provide 00050 * specific encodings and decodings, including encryption or compression. 00051 */ 00052 class Codec { 00053 public: 00054 /* 00055 * Standard constructor. 00056 */ 00057 Codec(); 00058 00059 /* 00060 * Standard destructor. 00061 */ 00062 virtual ~Codec(); 00063 00064 /* 00065 * Encodes a string. 00066 * 00067 * @param[in] decoded The unencoded string to encode is treated as binary 00068 * data, not a null-terminated c-string. 00069 * @param[out] encoded The encoded string should be treated as binary data, 00070 * not a null-terminated c-string. Use data(), not c_state() 00071 * to get at the bytes if needed. 00072 * @return ok if the string could be encoded. 00073 * 00074 * @see Decode 00075 */ 00076 virtual util::Status Encode( 00077 const StringPiece& decoded, string* encoded); 00078 00079 /* 00080 * Decodes a string. 00081 * 00082 * @param[in] encoded The encoded string to encode is treated as binary 00083 * data, not a null-terminated c-string. 00084 * @param[out] unencoded The decoded string should be treated as binary data, 00085 * not a null-terminated c-string. Use data(), not c_state() 00086 * to get at the bytes if needed. 00087 * @return ok if the string could be decoded. 00088 * 00089 * @see Encode 00090 */ 00091 virtual util::Status Decode( 00092 const StringPiece& encoded, string* unencoded); 00093 00094 /* 00095 * Creates a reader that encodes all the output of another reader. 00096 * 00097 * The default method returns an InMemory reader using the Decode method 00098 * on the input read into one monolithic string. 00099 * 00100 * Specialized encoder/decoders should override this to encode as the reader 00101 * streams if possible. 00102 * 00103 * @param[in] reader The caller maintains ownership of reader to encode. 00104 * However, they may pass ownership to the deleter. 00105 * @param[in] deleter If not NULL then it will be Run() when the reader is 00106 * destroyed. 00107 * @param[out] status ok on success, otherwise the reason for error. 00108 * @return ownership of a new reader that will return the decoded data. 00109 * This will never be null, though may be an InvalidDataReader 00110 * returning the same status on failure. 00111 * 00112 * @see NewManagedDecodingReader 00113 */ 00114 virtual DataReader* NewManagedEncodingReader( 00115 DataReader* reader, Closure* deleter, util::Status* status) = 0; 00116 00117 /* 00118 * Creates a reader that decodes all the output of another reader. 00119 * 00120 * The default method returns an InMemory reader using the Decode method 00121 * on the input read into one monolithic string. 00122 * 00123 * Specialized decoder/encoders should override this to decode as the reader 00124 * streams if possible. 00125 * 00126 * @param[in] reader The caller maintains ownership of reader to decode. 00127 * However, they may pass ownership to the deleter. 00128 * @param[in] deleter If not NULL then it will be Run() when the reader is 00129 * destroyed. 00130 * @param[out] status ok on success, otherwise the reason for error. 00131 * @return ownership of a new reader that will return the encoded data. 00132 * This will never be null, though may be an InvalidDataReader 00133 * returning the same status on failure. 00134 * 00135 * @see NewManagedEnccodingReader 00136 */ 00137 virtual DataReader* NewManagedDecodingReader( 00138 DataReader* reader, Closure* deleter, util::Status* status) = 0; 00139 00140 /* 00141 * Creates a reader that encodes the output of another reader. 00142 * 00143 * @param[in] reader The caller maintains ownership of the raeder to encode. 00144 * @param[out] status ok on success, otherwise the reason for error. 00145 * 00146 * @see NewManagedEncodingReader 00147 */ 00148 DataReader* NewUnmanagedEncodingReader( 00149 DataReader* reader, util::Status* status) { 00150 return NewManagedEncodingReader(reader, NULL, status); 00151 } 00152 00153 /* 00154 * Creates a reader that decodes the output of another reader. 00155 * 00156 * @param[in] reader The caller maintains ownership of the raeder to decode. 00157 * @param[out] status ok on success, otherwise the reason for error. 00158 * 00159 * @see NewManagedDecodingReader 00160 */ 00161 DataReader* NewUnmanagedDecodingReader( 00162 DataReader* reader, util::Status* status) { 00163 return NewManagedDecodingReader(reader, NULL, status); 00164 } 00165 00166 private: 00167 DISALLOW_COPY_AND_ASSIGN(Codec); 00168 }; 00169 00170 /* 00171 * A factory for creating Codec instances. 00172 * @ingroup DataLayerCodec 00173 * 00174 * This factory must be subclassed for a particualr concrete 00175 * <code>Codec</code>. The subclasses may provide additional configuration 00176 * parameters particular to the encoding/decoding scheme they implement. 00177 * 00178 * @see Codec 00179 */ 00180 class CodecFactory { 00181 public: 00182 /* 00183 * Standard constructor. 00184 */ 00185 CodecFactory(); 00186 00187 /* 00188 * Standard destructor. 00189 */ 00190 virtual ~CodecFactory(); 00191 00192 /* 00193 * The factory method that creates a new instance. 00194 * 00195 * @param[out] status ok on success, otherwise the reason for failure. 00196 * @return Ownership of the new instance is passed back to the caller. 00197 */ 00198 virtual Codec* New(util::Status* status) = 0; 00199 00200 private: 00201 DISALLOW_COPY_AND_ASSIGN(CodecFactory); 00202 }; 00203 00204 /* 00205 * A helper class for implementing CodecReaders. 00206 * 00207 * This class assumes bounded transformation sizes for a given input size. 00208 */ 00209 class CodecReader : public DataReader { 00210 public: 00211 /* 00212 * Standard constructor. 00213 * 00214 * @param[in] source The untarnsformed stream the codec is processing. 00215 * @param[in] deleter The deleter if this is to be a managed stream. 00216 * @param[in] chunk_size The size of source data to accumulate for each 00217 * transform (until the very last one) 00218 * @param[in] buffer_size The size to allocate for transformed data. 00219 * @param[in] encoding Whether this reader is encoding or decoding 00220 * determines whether we'll EncodeChunk or DecodeChunk. 00221 */ 00222 CodecReader( 00223 DataReader* source, Closure* deleter, 00224 int64 chunk_size, int64 buffer_size, 00225 bool encoding); 00226 00227 /* 00228 * Standard destructor. 00229 */ 00230 virtual ~CodecReader(); 00231 00232 /* 00233 * Called when resetting readers (seeking to start) 00234 */ 00235 virtual util::Status Init(); 00236 00237 protected: 00238 /* 00239 * Returns whether the reader was constructed for encoding or decoding. 00240 */ 00241 bool encoding() const { return encoding_; } 00242 00243 /* 00244 * Reads from internal transformed buffer, replentishing it as necessary. 00245 * 00246 * This method is compliant with the base DataReader::DoReadToBuffer 00247 * semantics. In particular, results are never non-negative and 0 does 00248 * not have any special meaning with regard to errors or being done. 00249 * 00250 * @param[in] max_bytes Max bytes to copy from buffer. 00251 * @param[in] storage The storage to read into. 00252 * @return Number of bytes read will never be more than the 00253 * constructed buffer_size, at least for the base class. 00254 */ 00255 virtual int64 DoReadToBuffer(int64 max_bytes, char* storage); 00256 00257 /* 00258 * Implements seeking through the transformed stream. 00259 * 00260 * This method is compliant with the base DataReader::DoSetOffset semantics. 00261 */ 00262 virtual int64 DoSetOffset(int64 to_offset); 00263 00264 /* 00265 * Hook for codecs to encode a chunk. 00266 * 00267 * @param[in] from The raw chunk from the source stream. 00268 * @param[in] final True if this is the final chunk. 00269 * @param[in] to The target buffer must be allocated big enough. 00270 * @param[in,out] to_len The size of the 'to' buffer on input. 00271 * The amount of data written into 'to' on output. 00272 */ 00273 virtual util::Status EncodeChunk( 00274 const StringPiece& from, bool final, char* to, int64* to_len) = 0; 00275 00276 /* 00277 * Hook for codecs to decode a chunk. 00278 * 00279 * @param[in] from The raw chunk from the source stream. 00280 * @param[in] final True if this is the final chunk. 00281 * @param[in] to The target buffer must be allocated big enough. 00282 * @param[in,out] to_len The size of the 'to' buffer on input. 00283 * The amount of data written into 'to' on output. 00284 */ 00285 virtual util::Status DecodeChunk( 00286 const StringPiece& from, bool final, char* to, int64* to_len) = 0; 00287 00288 private: 00289 struct Buffer; 00290 DataReader* source_; 00291 int64 chunk_size_; 00292 scoped_ptr<char[]> chunk_; 00293 scoped_ptr<Buffer> buffer_; // Waiting to read 00294 bool encoding_; 00295 bool read_final_; 00296 00297 /* 00298 * Returns how much buffered data is available. 00299 */ 00300 int MaybeFetchNextChunk(); 00301 DISALLOW_COPY_AND_ASSIGN(CodecReader); 00302 }; 00303 00304 } // namespace client 00305 00306 } // namespace googleapis 00307 #endif // APISERVING_CLIENTS_CPP_DATA_CODEC_H_