Writer.hh
00001
00019 #ifndef avro_Writer_hh__
00020 #define avro_Writer_hh__
00021
00022 #include <boost/noncopyable.hpp>
00023
00024 #include "buffer/Buffer.hh"
00025 #include "Zigzag.hh"
00026 #include "Types.hh"
00027 #include "Validator.hh"
00028
00029 namespace avro {
00030
00032
00033 template<class ValidatorType>
00034 class WriterImpl : private boost::noncopyable
00035 {
00036
00037 public:
00038
00039 WriterImpl() {}
00040
00041 explicit WriterImpl(const ValidSchema &schema) :
00042 validator_(schema)
00043 {}
00044
00045 void writeValue(const Null &) {
00046 validator_.checkTypeExpected(AVRO_NULL);
00047 }
00048
00049 void writeValue(bool val) {
00050 validator_.checkTypeExpected(AVRO_BOOL);
00051 int8_t byte = (val != 0);
00052 buffer_.writeTo(byte);
00053 }
00054
00055 void writeValue(int32_t val) {
00056 validator_.checkTypeExpected(AVRO_INT);
00057 boost::array<uint8_t, 5> bytes;
00058 size_t size = encodeInt32(val, bytes);
00059 buffer_.writeTo(reinterpret_cast<const char *>(bytes.data()), size);
00060 }
00061
00062 void writeValue(int64_t val) {
00063 validator_.checkTypeExpected(AVRO_LONG);
00064 putLong(val);
00065 }
00066
00067 void writeValue(float val) {
00068 validator_.checkTypeExpected(AVRO_FLOAT);
00069 union {
00070 float f;
00071 int32_t i;
00072 } v;
00073
00074 v.f = val;
00075 buffer_.writeTo(v.i);
00076 }
00077
00078 void writeValue(double val) {
00079 validator_.checkTypeExpected(AVRO_DOUBLE);
00080 union {
00081 double d;
00082 int64_t i;
00083 } v;
00084
00085 v.d = val;
00086 buffer_.writeTo(v.i);
00087 }
00088
00089 void writeValue(const std::string &val) {
00090 validator_.checkTypeExpected(AVRO_STRING);
00091 putBytes(val.c_str(), val.size());
00092 }
00093
00094 void writeBytes(const void *val, size_t size) {
00095 validator_.checkTypeExpected(AVRO_BYTES);
00096 putBytes(val, size);
00097 }
00098
00099 template <size_t N>
00100 void writeFixed(const uint8_t (&val)[N]) {
00101 validator_.checkFixedSizeExpected(N);
00102 buffer_.writeTo(reinterpret_cast<const char *>(val), N);
00103 }
00104
00105 template <size_t N>
00106 void writeFixed(const boost::array<uint8_t, N> &val) {
00107 validator_.checkFixedSizeExpected(val.size());
00108 buffer_.writeTo(reinterpret_cast<const char *>(val.data()), val.size());
00109 }
00110
00111 void writeRecord() {
00112 validator_.checkTypeExpected(AVRO_RECORD);
00113 validator_.checkTypeExpected(AVRO_LONG);
00114 validator_.setCount(1);
00115 }
00116
00117 void writeRecordEnd() {
00118 validator_.checkTypeExpected(AVRO_RECORD);
00119 validator_.checkTypeExpected(AVRO_LONG);
00120 validator_.setCount(0);
00121 }
00122
00123 void writeArrayBlock(int64_t size) {
00124 validator_.checkTypeExpected(AVRO_ARRAY);
00125 writeCount(size);
00126 }
00127
00128 void writeArrayEnd() {
00129 writeArrayBlock(0);
00130 }
00131
00132 void writeMapBlock(int64_t size) {
00133 validator_.checkTypeExpected(AVRO_MAP);
00134 writeCount(size);
00135 }
00136
00137 void writeMapEnd() {
00138 writeMapBlock(0);
00139 }
00140
00141 void writeUnion(int64_t choice) {
00142 validator_.checkTypeExpected(AVRO_UNION);
00143 writeCount(choice);
00144 }
00145
00146 void writeEnum(int64_t choice) {
00147 validator_.checkTypeExpected(AVRO_ENUM);
00148 writeCount(choice);
00149 }
00150
00151 InputBuffer buffer() const {
00152 return buffer_;
00153 }
00154
00155 private:
00156
00157 void putLong(int64_t val) {
00158 boost::array<uint8_t, 10> bytes;
00159 size_t size = encodeInt64(val, bytes);
00160 buffer_.writeTo(reinterpret_cast<const char *>(bytes.data()), size);
00161 }
00162
00163 void putBytes(const void *val, size_t size) {
00164 putLong(size);
00165 buffer_.writeTo(reinterpret_cast<const char *>(val), size);
00166 }
00167
00168 void writeCount(int64_t count) {
00169 validator_.checkTypeExpected(AVRO_LONG);
00170 validator_.setCount(count);
00171 putLong(count);
00172 }
00173
00174 ValidatorType validator_;
00175 OutputBuffer buffer_;
00176
00177 };
00178
00179 typedef WriterImpl<NullValidator> Writer;
00180 typedef WriterImpl<Validator> ValidatingWriter;
00181
00182 }
00183
00184 #endif