RTBKit  0.9
Open-source framework to create real-time ad bidding systems.
soa/logger/log_message_splitter.h
00001 /* log_message_splitter.h                                          -*- C++ -*-
00002    Jeremy Barnes, 6 February 2012
00003    Copyright (c) 2012 Datacratic.  All rights reserved.
00004 
00005 */
00006 #ifndef __logger__log_message_splitter_h__
00007 #define __logger__log_message_splitter_h__
00008 
00009 #include <string>
00010 
00011 #include "jml/arch/exception.h"
00012 
00013 namespace Datacratic {
00014 
00015 
00016 /*****************************************************************************/
00017 /* FIELD                                                                     */
00018 /*****************************************************************************/
00019 
00020 struct Field {
00021     const char * start;
00022     const char * end;
00023 
00024     size_t length() const { return end - start; }
00025     
00026     operator std::string() const { return std::string(start, end); };
00027 };
00028 
00029 inline std::ostream & operator << (std::ostream & stream, const Field & field)
00030 {
00031     return stream << field.operator std::string();
00032 }
00033 
00034 
00035 /*****************************************************************************/
00036 /* LOG MESSAGE SPLITTER                                                      */
00037 /*****************************************************************************/
00038 
00039 template<int maxFields>
00040 struct LogMessageSplitter {
00041 
00042     LogMessageSplitter(const std::string & str, char split = '\t')
00043         : str(str), data(this->str.c_str()), numFields(0)
00044     {
00045         numFields = 0;
00046         for (unsigned i = 0;  i <= maxFields;  ++i)
00047             offsets[i] = -1;
00048 
00049         const char * start = data;
00050         const char * end = start + str.size();
00051 
00052         while (start < end && numFields < maxFields) {
00053             offsets[numFields++] = start - data;
00054             while (start < end && *start != split)
00055                 ++start;
00056             if (start == end) break;
00057             ++start;  // skip delimiter
00058         }
00059 
00060         if (start == end)
00061             offsets[numFields] = end - data + 1;
00062         else offsets[numFields] = (start - data);
00063     }
00064 
00065     Field operator [] (int index) const
00066     {
00067         if (!(index >= 0) || index >= numFields || index >= maxFields)
00068             throw ML::Exception("invalid index");
00069         Field result;
00070         result.start = data + offsets[index];
00071         result.end = data + offsets[index + 1] - 1;
00072         return result;
00073     }
00074 
00075     size_t size() const { return numFields; }
00076 
00077     std::string str;
00078     const char * data;
00079     int numFields;
00080     int offsets[maxFields + 1];
00081 
00082 };
00083 
00084 } // namespace Datacratic
00085 
00086 #endif /* __logger__log_message_splitter_h__ */
00087 
00088 
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator