• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

LogFieldAliasMap.h

Go to the documentation of this file.
00001 /** @file
00002 
00003   This file implements an abstract class to map between numbers of type IntType
00004 
00005   @section license License
00006 
00007   Licensed to the Apache Software Foundation (ASF) under one
00008   or more contributor license agreements.  See the NOTICE file
00009   distributed with this work for additional information
00010   regarding copyright ownership.  The ASF licenses this file
00011   to you under the Apache License, Version 2.0 (the
00012   "License"); you may not use this file except in compliance
00013   with the License.  You may obtain a copy of the License at
00014 
00015       http://www.apache.org/licenses/LICENSE-2.0
00016 
00017   Unless required by applicable law or agreed to in writing, software
00018   distributed under the License is distributed on an "AS IS" BASIS,
00019   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00020   See the License for the specific language governing permissions and
00021   limitations under the License.
00022 
00023   @section description
00024   This file implements an abstract class to map between numbers of type IntType
00025   and strings. The purpose is to obtain one representation from the other so that
00026   easily remembered names can be used to refer to log fields of integer type.
00027  */
00028 
00029 
00030 #ifndef LOG_FIELD_ALIAS_MAP_H
00031 #define LOG_FIELD_ALIAS_MAP_H
00032 
00033 #include <stdarg.h>
00034 #include <string.h>
00035 
00036 #include "libts.h"
00037 #include "Ptr.h"
00038 #include "LogUtils.h"
00039 #include "ink_string.h"
00040 
00041 /*****************************************************************************
00042 
00043 The LogFieldAliasMap class is an abstract class used to provide an
00044 interface to map between numbers of type IntType and strings. The
00045 purpose is to obtain one representation from the other so that easy to
00046 remember names can be used to refer to log fields of integer type.
00047 
00048 The methods that subclasses should implement are:
00049 
00050 1) asInt(char *key, IntType *val)
00051 
00052 This method takes a string and sets the IntType argument to the
00053 corresponding value, (unless the string is invalid). It returns an
00054 error status.
00055 
00056 2) asString(IntType key, char *buf, size_t bufLen, size_t *numChars=0)
00057 
00058 This method takes an IntType key and writes its equivalent string to a
00059 bufer buf of length bufLen. It sets the number of written characters
00060 numChars (if numChars is not NULL), and returns an error status.
00061 
00062 The IntType to string conversion is used when unmarshaling data prior to
00063 writing to a log file, and the string to IntType conversion is used when
00064 building filters (so that the filter value can be specified as a string,
00065 but the actual field comparison is done between IntTypes).
00066 
00067 Note that LogFieldAliasMap is derived from RefCountObj, so once a map
00068 is constructed a pointer to it can be passed to other objects (e.g.,
00069 to a LogField object) without the object having to worry about freeing
00070 any memory the map may have allocated.
00071 
00072  *****************************************************************************/
00073 
00074 
00075 class LogFieldAliasMap:public RefCountObj
00076 {
00077 public:
00078 
00079   // the logging system assumes log entries of type sINT are
00080   // unsigned (signed?) integers (int64_t type) so we define IntType
00081   // to be unsigned (signed?)
00082   // The problem using the correct type is that the init method is
00083   // vararg. To make that work, we must use the "generic" int.
00084 
00085   typedef int64_t IntType;
00086   enum
00087   { ALL_OK = 0, INVALID_INT, INVALID_STRING, BUFFER_TOO_SMALL };
00088 
00089   virtual int asInt(char *key, IntType * val, bool case_sensitive = 0) const = 0;
00090   virtual int asString(IntType key, char *buf, size_t bufLen, size_t * numChars = 0) const = 0;
00091 };
00092 
00093 /*****************************************************************************
00094 
00095 A LogFieldAliasTable implements a LogFieldAliasMap through a
00096 straightforward table. The entries in the table are input with the
00097 init(numPairs, ...) method.  Arguments to this method are the number
00098 numPairs of table entries, followed by the entries themselves in the
00099 form integer, string. For example:
00100 
00101 table->init(3, 1, "one", 2, "two", 7, "seven")
00102 
00103  *****************************************************************************/
00104 
00105 struct LogFieldAliasTableEntry
00106 {
00107   bool valid;                   // entry in table is valid
00108   char *name;                   // the string equivalent
00109   size_t length;                // the length of the string
00110 
00111   LogFieldAliasTableEntry()
00112     : valid(false), name(NULL), length(0)
00113   { }
00114 };
00115 
00116 class LogFieldAliasTable:public LogFieldAliasMap
00117 {
00118 private:
00119   IntType m_min;                 // minimum numeric value
00120   IntType  m_max;                 // maximum numeric value
00121   IntType m_entries;             // number of entries in table
00122   LogFieldAliasTableEntry *m_table;     // array of table entries
00123 
00124 public:
00125   LogFieldAliasTable()
00126     : m_min(0), m_max(0), m_entries(0), m_table(0)
00127   { }
00128 
00129   ~LogFieldAliasTable() {
00130     delete[]m_table;
00131   }
00132 
00133   void init(size_t numPairs, ...);
00134 
00135   int asInt(char *key, IntType * val, bool case_sensitive) const
00136   {
00137     int retVal = INVALID_STRING;
00138 
00139     for (IntType i = 0; i < m_entries; i++)
00140     {
00141       bool found;
00142       if (m_table[i].valid)
00143       {
00144         if (case_sensitive) {
00145           found = (strcmp(key, m_table[i].name) == 0);
00146         } else
00147         {
00148           found = (strcasecmp(key, m_table[i].name) == 0);
00149         }
00150       } else {
00151         found = false;
00152       }
00153       if (found) {
00154         *val = (unsigned int) (i + m_min);
00155         retVal = ALL_OK;
00156         break;
00157       }
00158     }
00159 
00160     return retVal;
00161   }
00162 
00163   int asString(IntType key, char *buf, size_t bufLen, size_t * numCharsPtr = 0) const
00164   {
00165     int retVal;
00166     size_t numChars;
00167 
00168     size_t i = key - m_min;
00169     if (m_entries && key >= m_min && key <= m_max && m_table[i].valid)
00170     {
00171       size_t l = m_table[i].length;
00172       if (l < bufLen)
00173       {
00174         ink_strlcpy(buf, m_table[key - m_min].name, bufLen);
00175         numChars = l;
00176         retVal = ALL_OK;
00177       } else
00178       {
00179         numChars = 0;
00180         retVal = BUFFER_TOO_SMALL;
00181       }
00182     } else {
00183       numChars = 0;
00184       retVal = INVALID_INT;
00185     }
00186     if (numCharsPtr) {
00187       *numCharsPtr = numChars;
00188     }
00189     return retVal;
00190   }
00191 };
00192 
00193 /*****************************************************************************
00194 
00195 The LogFieldAliasTimehex class implements a LogFieldAliasMap that converts time
00196 from their integer value to the "hex" notation and back.
00197 
00198  *****************************************************************************/
00199 
00200 class LogFieldAliasTimeHex:public LogFieldAliasMap
00201 {
00202 public:
00203   int asInt(char *str, IntType * time, bool /* case_sensitive ATS_UNUSED */) const
00204   {
00205     unsigned long a;
00206     // coverity[secure_coding]
00207     if (sscanf(str, "%lx", (unsigned long *) &a) == 1) {
00208       *time = (IntType) a;
00209       return ALL_OK;
00210     } else
00211     {
00212       return INVALID_STRING;
00213     }
00214   }
00215 
00216   int asString(IntType time, char *buf, size_t bufLen, size_t * numCharsPtr = 0) const
00217   {
00218     return (LogUtils::timestamp_to_hex_str(time, buf, bufLen, numCharsPtr) ? BUFFER_TOO_SMALL : ALL_OK);
00219   }
00220 };
00221 
00222 
00223 
00224 //LOG_FIELD_ALIAS_MAP_H
00225 #endif

Generated by  doxygen 1.7.1