Avro C++
Specific.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_Codec_hh__
00020 #define avro_Codec_hh__
00021 
00022 #include <string>
00023 #include <vector>
00024 #include <map>
00025 #include <algorithm>
00026 
00027 #include "boost/array.hpp"
00028 
00029 #include "Config.hh"
00030 #include "Encoder.hh"
00031 #include "Decoder.hh"
00032 
00047 namespace avro {
00048 
00049 template <typename T> void encode(Encoder& e, const T& t);
00050 template <typename T> void decode(Decoder& d, T& t);
00051 
00060 template <typename T>
00061 struct codec_traits {
00062 };
00063 
00067 template <> struct codec_traits<bool> {
00071     static void encode(Encoder& e, bool b) {
00072         e.encodeBool(b);
00073     }
00074 
00078     static void decode(Decoder& d, bool& b) {
00079         b = d.decodeBool();
00080     }
00081 };
00082 
00086 template <> struct codec_traits<int32_t> {
00090     static void encode(Encoder& e, int32_t i) {
00091         e.encodeInt(i);
00092     }
00093 
00097     static void decode(Decoder& d, int32_t& i) {
00098         i = d.decodeInt();
00099     }
00100 };
00101 
00105 template <> struct codec_traits<int64_t> {
00109     static void encode(Encoder& e, int64_t l) {
00110         e.encodeLong(l);
00111     }
00112 
00116     static void decode(Decoder& d, int64_t& l) {
00117         l = d.decodeLong();
00118     }
00119 };
00120 
00124 template <> struct codec_traits<float> {
00128     static void encode(Encoder& e, float f) {
00129         e.encodeFloat(f);
00130     }
00131 
00135     static void decode(Decoder& d, float& f) {
00136         f = d.decodeFloat();
00137     }
00138 };
00139 
00143 template <> struct codec_traits<double> {
00147     static void encode(Encoder& e, double d) {
00148         e.encodeDouble(d);
00149     }
00150 
00154     static void decode(Decoder& d, double& dbl) {
00155         dbl = d.decodeDouble();
00156     }
00157 };
00158 
00162 template <> struct codec_traits<std::string> {
00166     static void encode(Encoder& e, const std::string& s) {
00167         e.encodeString(s);
00168     }
00169 
00173     static void decode(Decoder& d, std::string& s) {
00174         s = d.decodeString();
00175     }
00176 };
00177 
00181 template <> struct codec_traits<std::vector<uint8_t> > {
00185     static void encode(Encoder& e, const std::vector<uint8_t>& b) {
00186         e.encodeBytes(b);
00187     }
00188 
00192     static void decode(Decoder& d, std::vector<uint8_t>& s) {
00193         d.decodeBytes(s);
00194     }
00195 };
00196 
00200 template <size_t N> struct codec_traits<boost::array<uint8_t, N> > {
00204     static void encode(Encoder& e, const boost::array<uint8_t, N>& b) {
00205         e.encodeFixed(&b[0], N);
00206     }
00207 
00211     static void decode(Decoder& d, boost::array<uint8_t, N>& s) {
00212         std::vector<uint8_t> v(N);
00213         d.decodeFixed(N, v);
00214         std::copy(&v[0], &v[0] + N, &s[0]);
00215     }
00216 };
00217 
00221 template <typename T> struct codec_traits<std::vector<T> > {
00225     static void encode(Encoder& e, const std::vector<T>& b) {
00226         e.arrayStart();
00227         if (! b.empty()) {
00228             e.setItemCount(b.size());
00229             for (typename std::vector<T>::const_iterator it = b.begin();
00230                 it != b.end(); ++it) {
00231                 e.startItem();
00232                 avro::encode(e, *it);
00233             }
00234         }
00235         e.arrayEnd();
00236     }
00237 
00241     static void decode(Decoder& d, std::vector<T>& s) {
00242         s.clear();
00243         for (size_t n = d.arrayStart(); n != 0; n = d.arrayNext()) {
00244             for (size_t i = 0; i < n; ++i) {
00245                 T t;
00246                 avro::decode(d, t);
00247                 s.push_back(t);
00248             }
00249         }
00250     }
00251 };
00252 
00256 template <typename T> struct codec_traits<std::map<std::string, T> > {
00260     static void encode(Encoder& e, const std::map<std::string, T>& b) {
00261         e.mapStart();
00262         if (! b.empty()) {
00263             e.setItemCount(b.size());
00264             for (typename std::map<std::string, T>::const_iterator
00265                 it = b.begin();
00266                 it != b.end(); ++it) {
00267                 e.startItem();
00268                 avro::encode(e, it->first);
00269                 avro::encode(e, it->second);
00270             }
00271         }
00272         e.mapEnd();
00273     }
00274 
00278     static void decode(Decoder& d, std::map<std::string, T>& s) {
00279         s.clear();
00280         for (size_t n = d.mapStart(); n != 0; n = d.mapNext()) {
00281             for (size_t i = 0; i < n; ++i) {
00282                 std::string k;
00283                 avro::decode(d, k);
00284                 T t;
00285                 avro::decode(d, t);
00286                 s[k] = t;
00287             }
00288         }
00289     }
00290 };
00291 
00295 template <typename T>
00296 void encode(Encoder& e, const T& t) {
00297     codec_traits<T>::encode(e, t);
00298 }
00299 
00303 template <typename T>
00304 void decode(Decoder& d, T& t) {
00305     codec_traits<T>::decode(d, t);
00306 }
00307 
00308 }   // namespace avro
00309 #endif // avro_Codec_hh__
00310 
00311 
00312