Writer.hh

00001 /*
00002  * Licensed to the Apache Software Foundation (ASF) under one
00003  * or more contributor license agreements.  See the NOTICE file
00004  * distributed with this work for additional information
00005  * regarding copyright ownership.  The ASF licenses this file
00006  * to you under the Apache License, Version 2.0 (the
00007  * "License"); you may not use this file except in compliance
00008  * with the License.  You may obtain a copy of the License at
00009  *
00010  *     http://www.apache.org/licenses/LICENSE-2.0
00011  *
00012  * Unless required by applicable law or agreed to in writing, software
00013  * distributed under the License is distributed on an "AS IS" BASIS,
00014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  * See the License for the specific language governing permissions and
00016  * limitations under the License.
00017  */
00018 
00019 #ifndef avro_Writer_hh__
00020 #define avro_Writer_hh__
00021 
00022 #include <boost/noncopyable.hpp>
00023 
00024 #include "Config.hh"
00025 #include "buffer/Buffer.hh"
00026 #include "Zigzag.hh"
00027 #include "Types.hh"
00028 #include "Validator.hh"
00029 
00030 namespace avro {
00031 
00033 
00034 template<class ValidatorType>
00035 class WriterImpl : private boost::noncopyable
00036 {
00037 
00038   public:
00039 
00040     WriterImpl() {}
00041 
00042     explicit WriterImpl(const ValidSchema &schema) :
00043         validator_(schema) 
00044     {}
00045 
00046     void writeValue(const Null &) {
00047         validator_.checkTypeExpected(AVRO_NULL);
00048     }
00049 
00050     void writeValue(bool val) {
00051         validator_.checkTypeExpected(AVRO_BOOL);
00052         int8_t byte = (val != 0);
00053         buffer_.writeTo(byte);
00054     }
00055 
00056     void writeValue(int32_t val) {
00057         validator_.checkTypeExpected(AVRO_INT);
00058         boost::array<uint8_t, 5> bytes;
00059         size_t size = encodeInt32(val, bytes);
00060         buffer_.writeTo(reinterpret_cast<const char *>(bytes.data()), size);
00061     }
00062 
00063     void writeValue(int64_t val) {
00064         validator_.checkTypeExpected(AVRO_LONG);
00065         putLong(val);
00066     }
00067 
00068     void writeValue(float val) {
00069         validator_.checkTypeExpected(AVRO_FLOAT);
00070         union {
00071             float f;
00072             int32_t i;
00073         } v;
00074     
00075         v.f = val;
00076         buffer_.writeTo(v.i);
00077     }
00078 
00079     void writeValue(double val) {
00080         validator_.checkTypeExpected(AVRO_DOUBLE);
00081         union {
00082             double d;
00083             int64_t i;
00084         } v;
00085         
00086         v.d = val;
00087         buffer_.writeTo(v.i);
00088     }
00089 
00090     void writeValue(const std::string &val) {
00091         validator_.checkTypeExpected(AVRO_STRING);
00092         putBytes(val.c_str(), val.size());
00093     }
00094 
00095     void writeBytes(const void *val, size_t size) {
00096         validator_.checkTypeExpected(AVRO_BYTES);
00097         putBytes(val, size);
00098     }
00099 
00100     template <size_t N>
00101     void writeFixed(const uint8_t (&val)[N]) {
00102         validator_.checkFixedSizeExpected(N);
00103         buffer_.writeTo(reinterpret_cast<const char *>(val), N);
00104     }
00105 
00106     template <size_t N>
00107     void writeFixed(const boost::array<uint8_t, N> &val) {
00108         validator_.checkFixedSizeExpected(val.size());
00109         buffer_.writeTo(reinterpret_cast<const char *>(val.data()), val.size());
00110     }
00111 
00112     void writeRecord() {
00113         validator_.checkTypeExpected(AVRO_RECORD);
00114         validator_.checkTypeExpected(AVRO_LONG);
00115         validator_.setCount(1);
00116     }
00117 
00118     void writeRecordEnd() {
00119         validator_.checkTypeExpected(AVRO_RECORD);
00120         validator_.checkTypeExpected(AVRO_LONG);
00121         validator_.setCount(0);
00122     }
00123 
00124     void writeArrayBlock(int64_t size) {
00125         validator_.checkTypeExpected(AVRO_ARRAY);
00126         writeCount(size);
00127     }
00128 
00129     void writeArrayEnd() {
00130         writeArrayBlock(0);
00131     }
00132 
00133     void writeMapBlock(int64_t size) {
00134         validator_.checkTypeExpected(AVRO_MAP);
00135         writeCount(size);
00136     }
00137 
00138     void writeMapEnd() {
00139         writeMapBlock(0);
00140     }
00141 
00142     void writeUnion(int64_t choice) {
00143         validator_.checkTypeExpected(AVRO_UNION);
00144         writeCount(choice);
00145     }
00146 
00147     void writeEnum(int64_t choice) {
00148         validator_.checkTypeExpected(AVRO_ENUM);
00149         writeCount(choice);
00150     }
00151 
00152     InputBuffer buffer() const {
00153         return buffer_;
00154     }
00155 
00156   private:
00157 
00158     void putLong(int64_t val) {
00159         boost::array<uint8_t, 10> bytes;
00160         size_t size = encodeInt64(val, bytes);
00161         buffer_.writeTo(reinterpret_cast<const char *>(bytes.data()), size);
00162     }
00163 
00164     void putBytes(const void *val, size_t size) {
00165         putLong(size);
00166         buffer_.writeTo(reinterpret_cast<const char *>(val), size);
00167     }
00168 
00169     void writeCount(int64_t count) {
00170         validator_.checkTypeExpected(AVRO_LONG);
00171         validator_.setCount(count);
00172         putLong(count);
00173     }
00174 
00175     ValidatorType validator_;
00176     OutputBuffer buffer_;
00177 
00178 };
00179 
00180 typedef WriterImpl<NullValidator> Writer;
00181 typedef WriterImpl<Validator> ValidatingWriter;
00182 
00183 } // namespace avro
00184 
00185 #endif