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