| 1 | #pragma once | 
|---|
| 2 |  | 
|---|
| 3 | #include <IO/ReadBuffer.h> | 
|---|
| 4 | #include <IO/WriteBuffer.h> | 
|---|
| 5 | #include <IO/ReadHelpers.h> | 
|---|
| 6 | #include <IO/WriteHelpers.h> | 
|---|
| 7 |  | 
|---|
| 8 | #include <functional> | 
|---|
| 9 |  | 
|---|
| 10 |  | 
|---|
| 11 | namespace DB | 
|---|
| 12 | { | 
|---|
| 13 |  | 
|---|
| 14 | /** Implements the ability to write and read data in/from WriteBuffer/ReadBuffer | 
|---|
| 15 | *  with the help of << and >> operators and also manipulators, | 
|---|
| 16 | *  providing a way of using, similar to iostreams. | 
|---|
| 17 | * | 
|---|
| 18 | * It is neither a subset nor an extension of iostreams. | 
|---|
| 19 | * | 
|---|
| 20 | * Example usage: | 
|---|
| 21 | * | 
|---|
| 22 | *     DB::WriteBufferFromFileDescriptor buf(STDOUT_FILENO); | 
|---|
| 23 | *     buf << DB::double_quote << "Hello, world!" << '\n' << DB::flush; | 
|---|
| 24 | * | 
|---|
| 25 | * Outputs `char` type (usually it's Int8) as a symbol, not as a number. | 
|---|
| 26 | */ | 
|---|
| 27 |  | 
|---|
| 28 | /// Manipulators. | 
|---|
| 29 | enum EscapeManip        { escape };           /// For strings - escape special characters. In the rest, as usual. | 
|---|
| 30 | enum QuoteManip         { quote };            /// For strings, dates, datetimes - enclose in single quotes with escaping. In the rest, as usual. | 
|---|
| 31 | enum DoubleQuoteManip   { double_quote };     /// For strings, dates, datetimes - enclose in double quotes with escaping. In the rest, as usual. | 
|---|
| 32 | enum BinaryManip        { binary };           /// Output in binary format. | 
|---|
| 33 |  | 
|---|
| 34 | struct EscapeManipWriteBuffer        : std::reference_wrapper<WriteBuffer> { using std::reference_wrapper<WriteBuffer>::reference_wrapper; }; | 
|---|
| 35 | struct QuoteManipWriteBuffer         : std::reference_wrapper<WriteBuffer> { using std::reference_wrapper<WriteBuffer>::reference_wrapper; }; | 
|---|
| 36 | struct DoubleQuoteManipWriteBuffer   : std::reference_wrapper<WriteBuffer> { using std::reference_wrapper<WriteBuffer>::reference_wrapper; }; | 
|---|
| 37 | struct BinaryManipWriteBuffer        : std::reference_wrapper<WriteBuffer> { using std::reference_wrapper<WriteBuffer>::reference_wrapper; }; | 
|---|
| 38 |  | 
|---|
| 39 | struct EscapeManipReadBuffer         : std::reference_wrapper<ReadBuffer> { using std::reference_wrapper<ReadBuffer>::reference_wrapper; }; | 
|---|
| 40 | struct QuoteManipReadBuffer          : std::reference_wrapper<ReadBuffer> { using std::reference_wrapper<ReadBuffer>::reference_wrapper; }; | 
|---|
| 41 | struct DoubleQuoteManipReadBuffer    : std::reference_wrapper<ReadBuffer> { using std::reference_wrapper<ReadBuffer>::reference_wrapper; }; | 
|---|
| 42 | struct BinaryManipReadBuffer         : std::reference_wrapper<ReadBuffer> { using std::reference_wrapper<ReadBuffer>::reference_wrapper; }; | 
|---|
| 43 |  | 
|---|
| 44 |  | 
|---|
| 45 | template <typename T>     WriteBuffer & operator<< (WriteBuffer & buf, const T & x)        { writeText(x, buf);     return buf; } | 
|---|
| 46 | /// If you do not use the manipulators, the string is displayed without an escape, as is. | 
|---|
| 47 | template <> inline        WriteBuffer & operator<< (WriteBuffer & buf, const String & x)   { writeString(x, buf);   return buf; } | 
|---|
| 48 | template <> inline        WriteBuffer & operator<< (WriteBuffer & buf, const char & x)     { writeChar(x, buf);     return buf; } | 
|---|
| 49 |  | 
|---|
| 50 | inline WriteBuffer & operator<< (WriteBuffer & buf, const char * x)     { writeCString(x, buf); return buf; } | 
|---|
| 51 |  | 
|---|
| 52 | inline EscapeManipWriteBuffer      operator<< (WriteBuffer & buf, EscapeManip)      { return buf; } | 
|---|
| 53 | inline QuoteManipWriteBuffer       operator<< (WriteBuffer & buf, QuoteManip)       { return buf; } | 
|---|
| 54 | inline DoubleQuoteManipWriteBuffer operator<< (WriteBuffer & buf, DoubleQuoteManip) { return buf; } | 
|---|
| 55 | inline BinaryManipWriteBuffer      operator<< (WriteBuffer & buf, BinaryManip)      { return buf; } | 
|---|
| 56 |  | 
|---|
| 57 | template <typename T> WriteBuffer & operator<< (EscapeManipWriteBuffer buf,        const T & x) { writeText(x, buf.get());         return buf; } | 
|---|
| 58 | template <typename T> WriteBuffer & operator<< (QuoteManipWriteBuffer buf,         const T & x) { writeQuoted(x, buf.get());       return buf; } | 
|---|
| 59 | template <typename T> WriteBuffer & operator<< (DoubleQuoteManipWriteBuffer buf,   const T & x) { writeDoubleQuoted(x, buf.get()); return buf; } | 
|---|
| 60 | template <typename T> WriteBuffer & operator<< (BinaryManipWriteBuffer buf,        const T & x) { writeBinary(x, buf.get());       return buf; } | 
|---|
| 61 |  | 
|---|
| 62 | inline WriteBuffer & operator<< (EscapeManipWriteBuffer buf,      const char * x) { writeAnyEscapedString<'\''>(x, x + strlen(x), buf.get()); return buf; } | 
|---|
| 63 | inline WriteBuffer & operator<< (QuoteManipWriteBuffer buf,       const char * x) { writeAnyQuotedString<'\''>(x, x + strlen(x), buf.get()); return buf; } | 
|---|
| 64 | inline WriteBuffer & operator<< (DoubleQuoteManipWriteBuffer buf, const char * x) { writeAnyQuotedString<'"'>(x, x + strlen(x), buf.get()); return buf; } | 
|---|
| 65 | inline WriteBuffer & operator<< (BinaryManipWriteBuffer buf,      const char * x) { writeStringBinary(x, buf.get()); return buf; } | 
|---|
| 66 |  | 
|---|
| 67 | /// The manipulator calls the WriteBuffer method `next` - this makes the buffer reset. For nested buffers, the reset is not recursive. | 
|---|
| 68 | enum FlushManip { flush }; | 
|---|
| 69 |  | 
|---|
| 70 | inline WriteBuffer & operator<< (WriteBuffer & buf, FlushManip) { buf.next(); return buf; } | 
|---|
| 71 |  | 
|---|
| 72 |  | 
|---|
| 73 | template <typename T> ReadBuffer & operator>> (ReadBuffer & buf, T & x)              { readText(x, buf);     return buf; } | 
|---|
| 74 | template <> inline    ReadBuffer & operator>> (ReadBuffer & buf, String & x)         { readString(x, buf);   return buf; } | 
|---|
| 75 | template <> inline    ReadBuffer & operator>> (ReadBuffer & buf, char & x)           { readChar(x, buf);     return buf; } | 
|---|
| 76 |  | 
|---|
| 77 | /// If you specify a string literal for reading, this will mean - make sure there is a sequence of bytes and skip it. | 
|---|
| 78 | inline ReadBuffer & operator>> (ReadBuffer & buf, const char * x)     { assertString(x, buf); return buf; } | 
|---|
| 79 |  | 
|---|
| 80 | inline EscapeManipReadBuffer      operator>> (ReadBuffer & buf, EscapeManip)      { return buf; } | 
|---|
| 81 | inline QuoteManipReadBuffer       operator>> (ReadBuffer & buf, QuoteManip)       { return buf; } | 
|---|
| 82 | inline DoubleQuoteManipReadBuffer operator>> (ReadBuffer & buf, DoubleQuoteManip) { return buf; } | 
|---|
| 83 | inline BinaryManipReadBuffer      operator>> (ReadBuffer & buf, BinaryManip)      { return buf; } | 
|---|
| 84 |  | 
|---|
| 85 | template <typename T> ReadBuffer & operator>> (EscapeManipReadBuffer buf,      T & x) { readText(x, buf.get());         return buf; } | 
|---|
| 86 | template <typename T> ReadBuffer & operator>> (QuoteManipReadBuffer buf,       T & x) { readQuoted(x, buf.get());       return buf; } | 
|---|
| 87 | template <typename T> ReadBuffer & operator>> (DoubleQuoteManipReadBuffer buf, T & x) { readDoubleQuoted(x, buf.get()); return buf; } | 
|---|
| 88 | template <typename T> ReadBuffer & operator>> (BinaryManipReadBuffer buf,      T & x) { readBinary(x, buf.get());       return buf; } | 
|---|
| 89 |  | 
|---|
| 90 | } | 
|---|
| 91 |  | 
|---|