blob: c7de9b367b5b52ff6941aa65cb6b717938392b23 [file] [log] [blame]
// Copyright 2018 Google Inc.
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// See the License for the specific language governing permissions and
// limitations under the License.
#include "tink/util/status.h"
#include "tink/util/statusor.h"
namespace crypto {
namespace tink {
// Abstract interface similar to an output stream, and to
// Protocol Buffers' google::protobuf::io::ZeroCopyOutputStream.
class OutputStream {
OutputStream() {}
virtual ~OutputStream() {}
// Obtains a buffer into which data can be written. Any data written
// into this buffer will eventually (maybe instantly, maybe later on)
// be written to the output.
// Preconditions:
// * "data" is not NULL.
// Postconditions:
// * If the returned status is not OK, then an error occurred.
// All errors are permanent.
// * Otherwise, the returned value is the actual number of bytes
// in the buffer and "data" points to the buffer.
// * Ownership of this buffer remains with the stream, and the buffer
// remains valid only until some other non-const method of the stream
// is called or the stream is destroyed.
// * Any data which the caller stores in this buffer will eventually be
// written to the output (unless BackUp() is called).
// * It is legal for the returned buffer to have zero size, as long
// as repeatedly calling Next() eventually yields a buffer with non-zero
// size.
virtual crypto::tink::util::StatusOr<int> Next(void** data) = 0;
// Backs up a number of bytes, so that the end of the last buffer returned
// by Next() is not actually written. This is needed when you finish
// writing all the data you want to write, but the last buffer was bigger
// than you needed. You don't want to write a bunch of garbage after the
// end of your data, so you use BackUp() to back up.
// Preconditions:
// * The last call to Next() must have returned status OK.
// If there was no Next()-call yet, or the last one failed,
// BackUp()-call is ignored.
// * count must be less than or equal to the size of the last buffer
// returned by Next(). Non-positive count is ignored (no action on this
// stream), and count larger than the size of the last buffer is treated
// as equal to the size of the last buffer.
// * The caller must not have written anything to the last "count" bytes
// of that buffer.
// Postconditions:
// * The last "count" bytes of the last buffer returned by Next() will be
// ignored.
// * Repeated calls to BackUp() accumulate:
// BackUp(a);
// Backup(b);
// is equivalent to
// Backup(c);
// with c = max(0, a) + max(0, b).
// * The actual result of BackUp()-call can be verified via Position().
virtual void BackUp(int count) = 0;
// Closes this output stream. It flushes all the data from the last buffer
// returned by Next(), (except the ones backed up via BackUp(), if any)
// Returns a non-OK status if some error occurred.
// Preconditions:
// * The stream is not closed yet,
// * The last call to Next() did not return an error.
// Postconditions:
// * Writing to the stream is not possible any more, and all calls
// to non-const methods will fail.
virtual crypto::tink::util::Status Close() = 0;
// Returns the total number of bytes written since this object was created.
// Preconditions:
// * The most recent call to Next() (if any) was successful, or the stream
// was successfully closed.
// Postconditions:
// * The returned position includes the bytes from the most recent
// successful call to Next(), excluding the ones that were backed up
// via BackUp() (if any).
// * If the last call to Next() ended with a failure, -1 is returned;
virtual int64_t Position() const = 0;
} // namespace tink
} // namespace crypto