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 "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 } // namespace avro
00183 
00184 #endif