capnproto

FORK: Cap'n Proto serialization/RPC system - core tools and C++ library
git clone https://git.neptards.moe/neptards/capnproto.git
Log | Files | Refs | README | LICENSE

serialize-packed.h (5347B)


      1 // Copyright (c) 2013-2014 Sandstorm Development Group, Inc. and contributors
      2 // Licensed under the MIT License:
      3 //
      4 // Permission is hereby granted, free of charge, to any person obtaining a copy
      5 // of this software and associated documentation files (the "Software"), to deal
      6 // in the Software without restriction, including without limitation the rights
      7 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      8 // copies of the Software, and to permit persons to whom the Software is
      9 // furnished to do so, subject to the following conditions:
     10 //
     11 // The above copyright notice and this permission notice shall be included in
     12 // all copies or substantial portions of the Software.
     13 //
     14 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
     15 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
     16 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
     17 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
     18 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
     19 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
     20 // THE SOFTWARE.
     21 
     22 #pragma once
     23 
     24 #include "serialize.h"
     25 
     26 CAPNP_BEGIN_HEADER
     27 
     28 namespace capnp {
     29 
     30 namespace _ {  // private
     31 
     32 class PackedInputStream: public kj::InputStream {
     33   // An input stream that unpacks packed data with a picky constraint:  The caller must read data
     34   // in the exact same size and sequence as the data was written to PackedOutputStream.
     35 
     36 public:
     37   explicit PackedInputStream(kj::BufferedInputStream& inner);
     38   KJ_DISALLOW_COPY(PackedInputStream);
     39   ~PackedInputStream() noexcept(false);
     40 
     41   // implements InputStream ------------------------------------------
     42   size_t tryRead(void* buffer, size_t minBytes, size_t maxBytes) override;
     43   void skip(size_t bytes) override;
     44 
     45 private:
     46   kj::BufferedInputStream& inner;
     47 };
     48 
     49 class PackedOutputStream: public kj::OutputStream {
     50   // An output stream that packs data. Buffers passed to `write()` must be word-aligned.
     51 public:
     52   explicit PackedOutputStream(kj::BufferedOutputStream& inner);
     53   KJ_DISALLOW_COPY(PackedOutputStream);
     54   ~PackedOutputStream() noexcept(false);
     55 
     56   // implements OutputStream -----------------------------------------
     57   void write(const void* buffer, size_t bytes) override;
     58 
     59 private:
     60   kj::BufferedOutputStream& inner;
     61 };
     62 
     63 }  // namespace _ (private)
     64 
     65 class PackedMessageReader: private _::PackedInputStream, public InputStreamMessageReader {
     66 public:
     67   PackedMessageReader(kj::BufferedInputStream& inputStream, ReaderOptions options = ReaderOptions(),
     68                       kj::ArrayPtr<word> scratchSpace = nullptr);
     69   KJ_DISALLOW_COPY(PackedMessageReader);
     70   ~PackedMessageReader() noexcept(false);
     71 };
     72 
     73 class PackedFdMessageReader: private kj::FdInputStream, private kj::BufferedInputStreamWrapper,
     74                              public PackedMessageReader {
     75 public:
     76   PackedFdMessageReader(int fd, ReaderOptions options = ReaderOptions(),
     77                         kj::ArrayPtr<word> scratchSpace = nullptr);
     78   // Read message from a file descriptor, without taking ownership of the descriptor.
     79   // Note that if you want to reuse the descriptor after the reader is destroyed, you'll need to
     80   // seek it, since otherwise the position is unspecified.
     81 
     82   PackedFdMessageReader(kj::AutoCloseFd fd, ReaderOptions options = ReaderOptions(),
     83                         kj::ArrayPtr<word> scratchSpace = nullptr);
     84   // Read a message from a file descriptor, taking ownership of the descriptor.
     85 
     86   KJ_DISALLOW_COPY(PackedFdMessageReader);
     87 
     88   ~PackedFdMessageReader() noexcept(false);
     89 };
     90 
     91 void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder);
     92 void writePackedMessage(kj::BufferedOutputStream& output,
     93                         kj::ArrayPtr<const kj::ArrayPtr<const word>> segments);
     94 // Write a packed message to a buffered output stream.
     95 
     96 void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder);
     97 void writePackedMessage(kj::OutputStream& output,
     98                         kj::ArrayPtr<const kj::ArrayPtr<const word>> segments);
     99 // Write a packed message to an unbuffered output stream.  If you intend to write multiple messages
    100 // in succession, consider wrapping your output in a buffered stream in order to reduce system
    101 // call overhead.
    102 
    103 void writePackedMessageToFd(int fd, MessageBuilder& builder);
    104 void writePackedMessageToFd(int fd, kj::ArrayPtr<const kj::ArrayPtr<const word>> segments);
    105 // Write a single packed message to the file descriptor.
    106 
    107 size_t computeUnpackedSizeInWords(kj::ArrayPtr<const byte> packedBytes);
    108 // Computes the number of words to which the given packed bytes will unpack. Not intended for use
    109 // in performance-sensitive situations.
    110 
    111 // =======================================================================================
    112 // inline stuff
    113 
    114 inline void writePackedMessage(kj::BufferedOutputStream& output, MessageBuilder& builder) {
    115   writePackedMessage(output, builder.getSegmentsForOutput());
    116 }
    117 
    118 inline void writePackedMessage(kj::OutputStream& output, MessageBuilder& builder) {
    119   writePackedMessage(output, builder.getSegmentsForOutput());
    120 }
    121 
    122 inline void writePackedMessageToFd(int fd, MessageBuilder& builder) {
    123   writePackedMessageToFd(fd, builder.getSegmentsForOutput());
    124 }
    125 
    126 }  // namespace capnp
    127 
    128 CAPNP_END_HEADER