| /** @file |
| |
| This file implements an abstract class to map between numbers of type IntType |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); you may not use this file except in compliance |
| with the License. You may obtain a copy of the License at |
| |
| http://www.apache.org/licenses/LICENSE-2.0 |
| |
| Unless required by applicable law or agreed to in writing, software |
| distributed under the License is distributed on an "AS IS" BASIS, |
| WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| See the License for the specific language governing permissions and |
| limitations under the License. |
| |
| @section description |
| This file implements an abstract class to map between numbers of type IntType |
| and strings. The purpose is to obtain one representation from the other so that |
| easily remembered names can be used to refer to log fields of integer type. |
| */ |
| |
| #pragma once |
| |
| #include <cstdarg> |
| #include <cstring> |
| |
| #include "tscore/ink_platform.h" |
| #include "tscore/Ptr.h" |
| #include "LogUtils.h" |
| #include "tscore/ink_string.h" |
| |
| /***************************************************************************** |
| |
| The LogFieldAliasMap class is an abstract class used to provide an |
| interface to map between numbers of type IntType and strings. The |
| purpose is to obtain one representation from the other so that easy to |
| remember names can be used to refer to log fields of integer type. |
| |
| The methods that subclasses should implement are: |
| |
| 1) asInt(char *key, IntType *val) |
| |
| This method takes a string and sets the IntType argument to the |
| corresponding value, (unless the string is invalid). It returns an |
| error status. |
| |
| 2) asString(IntType key, char *buf, size_t bufLen, size_t *numChars=0) |
| |
| This method takes an IntType key and writes its equivalent string to a |
| buffer buf of length bufLen. It sets the number of written characters |
| numChars (if numChars is not NULL), and returns an error status. |
| |
| The IntType to string conversion is used when unmarshaling data prior to |
| writing to a log file, and the string to IntType conversion is used when |
| building filters (so that the filter value can be specified as a string, |
| but the actual field comparison is done between IntTypes). |
| |
| Note that LogFieldAliasMap is derived from RefCountObj, so once a map |
| is constructed a pointer to it can be passed to other objects (e.g., |
| to a LogField object) without the object having to worry about freeing |
| any memory the map may have allocated. |
| |
| *****************************************************************************/ |
| |
| class LogFieldAliasMap : public RefCountObj |
| { |
| public: |
| // the logging system assumes log entries of type sINT are |
| // unsigned (signed?) integers (int64_t type) so we define IntType |
| // to be unsigned (signed?) |
| // The problem using the correct type is that the init method is |
| // vararg. To make that work, we must use the "generic" int. |
| |
| typedef int64_t IntType; |
| enum { |
| ALL_OK = 0, |
| INVALID_INT, |
| INVALID_STRING, |
| BUFFER_TOO_SMALL, |
| }; |
| |
| virtual int asInt(char *key, IntType *val, bool case_sensitive = false) const = 0; |
| virtual int asString(IntType key, char *buf, size_t bufLen, size_t *numChars = nullptr) const = 0; |
| }; |
| |
| /***************************************************************************** |
| |
| A LogFieldAliasTable implements a LogFieldAliasMap through a |
| straightforward table. The entries in the table are input with the |
| init(numPairs, ...) method. Arguments to this method are the number |
| numPairs of table entries, followed by the entries themselves in the |
| form integer, string. For example: |
| |
| table->init(3, 1, "one", 2, "two", 7, "seven") |
| |
| *****************************************************************************/ |
| |
| struct LogFieldAliasTableEntry { |
| bool valid = false; // entry in table is valid |
| char *name = nullptr; // the string equivalent |
| size_t length = 0; // the length of the string |
| |
| LogFieldAliasTableEntry() {} |
| ~LogFieldAliasTableEntry() |
| { |
| if (name) { |
| free(name); |
| } |
| } |
| }; |
| |
| class LogFieldAliasTable : public LogFieldAliasMap |
| { |
| private: |
| IntType m_min = 0; // minimum numeric value |
| IntType m_max = 0; // maximum numeric value |
| IntType m_entries = 0; // number of entries in table |
| LogFieldAliasTableEntry *m_table = nullptr; // array of table entries |
| |
| public: |
| LogFieldAliasTable() {} |
| ~LogFieldAliasTable() override { delete[] m_table; } |
| void init(size_t numPairs, ...); |
| |
| int |
| asInt(char *key, IntType *val, bool case_sensitive) const override |
| { |
| int retVal = INVALID_STRING; |
| |
| for (IntType i = 0; i < m_entries; i++) { |
| bool found; |
| if (m_table[i].valid) { |
| if (case_sensitive) { |
| found = (strcmp(key, m_table[i].name) == 0); |
| } else { |
| found = (strcasecmp(key, m_table[i].name) == 0); |
| } |
| } else { |
| found = false; |
| } |
| if (found) { |
| *val = (unsigned int)(i + m_min); |
| retVal = ALL_OK; |
| break; |
| } |
| } |
| |
| return retVal; |
| } |
| |
| int |
| asString(IntType key, char *buf, size_t bufLen, size_t *numCharsPtr = nullptr) const override |
| { |
| int retVal; |
| size_t numChars; |
| |
| size_t i = key - m_min; |
| if (m_entries && key >= m_min && key <= m_max && m_table[i].valid) { |
| size_t l = m_table[i].length; |
| if (l < bufLen) { |
| ink_strlcpy(buf, m_table[key - m_min].name, bufLen); |
| numChars = l; |
| retVal = ALL_OK; |
| } else { |
| numChars = 0; |
| retVal = BUFFER_TOO_SMALL; |
| } |
| } else { |
| numChars = 0; |
| retVal = INVALID_INT; |
| } |
| if (numCharsPtr) { |
| *numCharsPtr = numChars; |
| } |
| return retVal; |
| } |
| }; |
| |
| // LOG_FIELD_ALIAS_MAP_H |