1*e7b1675dSTing-Kang Chang // Copyright 2018 Google Inc. 2*e7b1675dSTing-Kang Chang // 3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License"); 4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License. 5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at 6*e7b1675dSTing-Kang Chang // 7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0 8*e7b1675dSTing-Kang Chang // 9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software 10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS, 11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and 13*e7b1675dSTing-Kang Chang // limitations under the License. 14*e7b1675dSTing-Kang Chang // 15*e7b1675dSTing-Kang Chang /////////////////////////////////////////////////////////////////////////////// 16*e7b1675dSTing-Kang Chang 17*e7b1675dSTing-Kang Chang #ifndef TINK_OUTPUT_STREAM_H_ 18*e7b1675dSTing-Kang Chang #define TINK_OUTPUT_STREAM_H_ 19*e7b1675dSTing-Kang Chang 20*e7b1675dSTing-Kang Chang #include "tink/util/status.h" 21*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h" 22*e7b1675dSTing-Kang Chang 23*e7b1675dSTing-Kang Chang namespace crypto { 24*e7b1675dSTing-Kang Chang namespace tink { 25*e7b1675dSTing-Kang Chang 26*e7b1675dSTing-Kang Chang // Abstract interface similar to an output stream, and to 27*e7b1675dSTing-Kang Chang // Protocol Buffers' google::protobuf::io::ZeroCopyOutputStream. 28*e7b1675dSTing-Kang Chang class OutputStream { 29*e7b1675dSTing-Kang Chang public: 30*e7b1675dSTing-Kang Chang OutputStream() = default; 31*e7b1675dSTing-Kang Chang virtual ~OutputStream() = default; 32*e7b1675dSTing-Kang Chang 33*e7b1675dSTing-Kang Chang // Obtains a buffer into which data can be written. Any data written 34*e7b1675dSTing-Kang Chang // into this buffer will eventually (maybe instantly, maybe later on) 35*e7b1675dSTing-Kang Chang // be written to the output. 36*e7b1675dSTing-Kang Chang // 37*e7b1675dSTing-Kang Chang // Preconditions: 38*e7b1675dSTing-Kang Chang // * "data" is not NULL. 39*e7b1675dSTing-Kang Chang // 40*e7b1675dSTing-Kang Chang // Postconditions: 41*e7b1675dSTing-Kang Chang // * If the returned status is not OK, then an error occurred. 42*e7b1675dSTing-Kang Chang // All errors are permanent. 43*e7b1675dSTing-Kang Chang // * Otherwise, the returned value is the actual number of bytes 44*e7b1675dSTing-Kang Chang // in the buffer and "data" points to the buffer. 45*e7b1675dSTing-Kang Chang // * Ownership of this buffer remains with the stream, and the buffer 46*e7b1675dSTing-Kang Chang // remains valid only until some other non-const method of the stream 47*e7b1675dSTing-Kang Chang // is called or the stream is destroyed. 48*e7b1675dSTing-Kang Chang // * Any data which the caller stores in this buffer will eventually be 49*e7b1675dSTing-Kang Chang // written to the output (unless BackUp() is called). 50*e7b1675dSTing-Kang Chang // * It is legal for the returned buffer to have zero size, as long 51*e7b1675dSTing-Kang Chang // as repeatedly calling Next() eventually yields a buffer with non-zero 52*e7b1675dSTing-Kang Chang // size. 53*e7b1675dSTing-Kang Chang virtual crypto::tink::util::StatusOr<int> Next(void** data) = 0; 54*e7b1675dSTing-Kang Chang 55*e7b1675dSTing-Kang Chang // Backs up a number of bytes, so that the end of the last buffer returned 56*e7b1675dSTing-Kang Chang // by Next() is not actually written. This is needed when you finish 57*e7b1675dSTing-Kang Chang // writing all the data you want to write, but the last buffer was bigger 58*e7b1675dSTing-Kang Chang // than you needed. You don't want to write a bunch of garbage after the 59*e7b1675dSTing-Kang Chang // end of your data, so you use BackUp() to back up. 60*e7b1675dSTing-Kang Chang // 61*e7b1675dSTing-Kang Chang // Preconditions: 62*e7b1675dSTing-Kang Chang // * The last call to Next() must have returned status OK. 63*e7b1675dSTing-Kang Chang // If there was no Next()-call yet, or the last one failed, 64*e7b1675dSTing-Kang Chang // BackUp()-call is ignored. 65*e7b1675dSTing-Kang Chang // * count must be less than or equal to the size of the last buffer 66*e7b1675dSTing-Kang Chang // returned by Next(). Non-positive count is ignored (no action on this 67*e7b1675dSTing-Kang Chang // stream), and count larger than the size of the last buffer is treated 68*e7b1675dSTing-Kang Chang // as equal to the size of the last buffer. 69*e7b1675dSTing-Kang Chang // * The caller must not have written anything to the last "count" bytes 70*e7b1675dSTing-Kang Chang // of that buffer. 71*e7b1675dSTing-Kang Chang // 72*e7b1675dSTing-Kang Chang // Postconditions: 73*e7b1675dSTing-Kang Chang // * The last "count" bytes of the last buffer returned by Next() will be 74*e7b1675dSTing-Kang Chang // ignored. 75*e7b1675dSTing-Kang Chang // * Repeated calls to BackUp() accumulate: 76*e7b1675dSTing-Kang Chang // BackUp(a); 77*e7b1675dSTing-Kang Chang // Backup(b); 78*e7b1675dSTing-Kang Chang // is equivalent to 79*e7b1675dSTing-Kang Chang // Backup(c); 80*e7b1675dSTing-Kang Chang // with c = max(0, a) + max(0, b). 81*e7b1675dSTing-Kang Chang // * The actual result of BackUp()-call can be verified via Position(). 82*e7b1675dSTing-Kang Chang virtual void BackUp(int count) = 0; 83*e7b1675dSTing-Kang Chang 84*e7b1675dSTing-Kang Chang // Closes this output stream. It flushes all the data from the last buffer 85*e7b1675dSTing-Kang Chang // returned by Next(), (except the ones backed up via BackUp(), if any) 86*e7b1675dSTing-Kang Chang // Returns a non-OK status if some error occurred. 87*e7b1675dSTing-Kang Chang // 88*e7b1675dSTing-Kang Chang // Preconditions: 89*e7b1675dSTing-Kang Chang // * The stream is not closed yet, 90*e7b1675dSTing-Kang Chang // * The last call to Next() did not return an error. 91*e7b1675dSTing-Kang Chang // 92*e7b1675dSTing-Kang Chang // Postconditions: 93*e7b1675dSTing-Kang Chang // * Writing to the stream is not possible any more, and all calls 94*e7b1675dSTing-Kang Chang // to non-const methods will fail. 95*e7b1675dSTing-Kang Chang virtual crypto::tink::util::Status Close() = 0; 96*e7b1675dSTing-Kang Chang 97*e7b1675dSTing-Kang Chang // Returns the total number of bytes written since this object was created. 98*e7b1675dSTing-Kang Chang // Preconditions: 99*e7b1675dSTing-Kang Chang // * The most recent call to Next() (if any) was successful, or the stream 100*e7b1675dSTing-Kang Chang // was successfully closed. 101*e7b1675dSTing-Kang Chang // 102*e7b1675dSTing-Kang Chang // Postconditions: 103*e7b1675dSTing-Kang Chang // * The returned position includes the bytes from the most recent 104*e7b1675dSTing-Kang Chang // successful call to Next(), excluding the ones that were backed up 105*e7b1675dSTing-Kang Chang // via BackUp() (if any). 106*e7b1675dSTing-Kang Chang // * If the last call to Next() ended with a failure, -1 is returned; 107*e7b1675dSTing-Kang Chang virtual int64_t Position() const = 0; 108*e7b1675dSTing-Kang Chang }; 109*e7b1675dSTing-Kang Chang 110*e7b1675dSTing-Kang Chang } // namespace tink 111*e7b1675dSTing-Kang Chang } // namespace crypto 112*e7b1675dSTing-Kang Chang 113*e7b1675dSTing-Kang Chang #endif // TINK_OUTPUT_STREAM_H_ 114