LogCabin
Core/ProtoBuf.h
Go to the documentation of this file.
00001 /* Copyright (c) 2012 Stanford University
00002  * Copyright (c) 2015 Diego Ongaro
00003  *
00004  * Permission to use, copy, modify, and distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR(S) DISCLAIM ALL WARRANTIES
00009  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
00010  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL AUTHORS BE LIABLE FOR
00011  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
00012  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
00013  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
00014  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 #include <google/protobuf/message.h>
00018 #include <memory>
00019 #include <string>
00020 
00021 #include "Core/Buffer.h"
00022 
00023 /**
00024  * \file
00025  * Utilities for dealing with protocol buffers.
00026  */
00027 
00028 #ifndef LOGCABIN_CORE_PROTOBUF_H
00029 #define LOGCABIN_CORE_PROTOBUF_H
00030 
00031 namespace google {
00032 namespace protobuf {
00033 
00034 /**
00035  * Equality for protocol buffers so that they can be used in EXPECT_EQ.
00036  * This is useful for testing.
00037  */
00038 bool operator==(const Message& a, const Message& b);
00039 
00040 /**
00041  * Inequality for protocol buffers so that they can be used in EXPECT_NE.
00042  * This is useful for testing.
00043  */
00044 bool operator!=(const Message& a, const Message& b);
00045 
00046 // Equality and inequality between protocol buffers and their text format
00047 // representations. These are useful for testing.
00048 bool operator==(const Message& a, const std::string& b);
00049 bool operator==(const std::string& a, const Message& b);
00050 bool operator!=(const Message& a, const std::string& b);
00051 bool operator!=(const std::string& a, const Message& b);
00052 
00053 } // namespace google::protobuf
00054 } // namespace google
00055 
00056 namespace LogCabin {
00057 namespace Core {
00058 namespace ProtoBuf {
00059 
00060 namespace Internal {
00061 
00062 /// Helper for fromString template.
00063 void fromString(const std::string& str, google::protobuf::Message& protoBuf);
00064 
00065 } // namespace LogCabin::ProtoBuf::Internal
00066 
00067 /**
00068  * Create a protocol buffer message form a text format.
00069  * This is useful for testing.
00070  * \tparam ProtoBuf
00071  *      A derived class of ProtoBuf::Message.
00072  * \param str
00073  *      The string representation of the protocol buffer message.
00074  *      Fields that are missing will not throw an error, but the resulting
00075  *      protocol buffer may be less useful.
00076  * \return
00077  *      The parsed protocol buffer.
00078  */
00079 template<typename ProtoBuf>
00080 ProtoBuf
00081 fromString(const std::string& str)
00082 {
00083     ProtoBuf protoBuf;
00084     Internal::fromString(str, protoBuf);
00085     return protoBuf;
00086 }
00087 
00088 /**
00089  * Dumps a protocol buffer message.
00090  * This is useful for debugging and for testing.
00091  *
00092  * \param protoBuf
00093  *      The protocol buffer message to dump out. It is safe to call this even
00094  *      if you haven't filled in all required fields, but the generated string
00095  *      will not be directly parse-able.
00096  * \param forCopyingIntoTest
00097  *      If set to true, this will return a string in a format most useful for
00098  *      writing unit tests. You can basically copy and paste this from your
00099  *      terminal into your test file without manual processing. If set to false
00100  *      (default), the output will be nicer to read but harder to copy into a
00101  *      test file.
00102  * \return
00103  *      Textual representation. This will be printable ASCII; binary will be
00104  *      escaped.
00105  */
00106 std::string
00107 dumpString(const google::protobuf::Message& protoBuf,
00108            bool forCopyingIntoTest = false);
00109 
00110 /**
00111  * Copy the contents of a protocol buffer into a new one.
00112  */
00113 std::unique_ptr<google::protobuf::Message>
00114 copy(const google::protobuf::Message& protoBuf);
00115 
00116 /**
00117  * Parse a protocol buffer message out of a Core::Buffer.
00118  * \param from
00119  *      The Core::Buffer from which to extract a protocol buffer.
00120  * \param[out] to
00121  *      The empty protocol buffer to fill in with the contents of the
00122  *      Core::Buffer.
00123  * \param skipBytes
00124  *      The number of bytes to skip at the beginning of 'from' (defaults to 0).
00125  * \return
00126  *      True if the protocol buffer was parsed successfully; false otherwise
00127  *      (for example, if a required field is missing).
00128  */
00129 bool
00130 parse(const Core::Buffer& from,
00131       google::protobuf::Message& to,
00132       uint32_t skipBytes = 0);
00133 
00134 /**
00135  * Serialize a protocol buffer message into a Core::Buffer.
00136  * \param from
00137  *      The protocol buffer containing the contents to serialize into the
00138  *      Core::Buffer. All required fields must be set or this will PANIC.
00139  * \param[out] to
00140  *      The Core::Buffer to fill in with the contents of the protocol buffer.
00141  * \param skipBytes
00142  *      The number of bytes to allocate at the beginning of 'to' but leave
00143  *      uninitialized for someone else to fill in (defaults to 0).
00144  */
00145 void
00146 serialize(const google::protobuf::Message& from,
00147           Core::Buffer& to,
00148           uint32_t skipBytes = 0);
00149 
00150 /**
00151  * An abstract stream from which ProtoBufs may be read.
00152  */
00153 struct InputStream {
00154     /**
00155      * Destructor.
00156      */
00157     virtual ~InputStream() {}
00158     /**
00159      * Return the number of bytes read so far.
00160      */
00161     virtual uint64_t getBytesRead() const = 0;
00162     /**
00163      * Read a ProtoBuf message from the stream. 
00164      * \return
00165      *      Empty string if successful, otherwise an error message if an error
00166      *      occurred. The stream is probably no longer usable after an error.
00167      */
00168     virtual std::string readMessage(google::protobuf::Message& message) = 0;
00169     /**
00170      * Read some raw bytes from the stream.
00171      * \return
00172      *      The number of bytes read before the end of the stream was reached,
00173      *      up to 'length'.
00174      */
00175     virtual uint64_t readRaw(void* data, uint64_t length) = 0;
00176 };
00177 
00178 /**
00179  * An abstract stream to which ProtoBufs may be written.
00180  */
00181 struct OutputStream {
00182     /**
00183      * Destructor.
00184      */
00185     virtual ~OutputStream() {}
00186     /**
00187      * Return the number of bytes written so far.
00188      */
00189     virtual uint64_t getBytesWritten() const = 0;
00190     /**
00191      * Write the given ProtoBuf message to the stream.
00192      */
00193     virtual void writeMessage(const google::protobuf::Message& message) = 0;
00194     /**
00195      * Write some raw bytes to the stream.
00196      */
00197     virtual void writeRaw(const void* data, uint64_t length) = 0;
00198 };
00199 
00200 } // namespace LogCabin::Core::ProtoBuf
00201 } // namespace LogCabin::Core
00202 } // namespace LogCabin
00203 
00204 #endif /* LOGCABIN_CORE_PROTOBUF_H */
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines