mirror of
https://github.com/valitydev/osquery-1.git
synced 2024-11-08 02:18:53 +00:00
205 lines
6.0 KiB
C++
205 lines
6.0 KiB
C++
/*
|
|
* Copyright (c) 2014-present, Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD-style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <errno.h>
|
|
#include <math.h>
|
|
#include <string.h>
|
|
|
|
#include <functional>
|
|
|
|
#include <sqlite3.h>
|
|
|
|
namespace osquery {
|
|
|
|
using DoubleDoubleFunction = std::function<double(double)>;
|
|
|
|
/**
|
|
* @brief Call a math function that takes a double and returns a double.
|
|
*/
|
|
static void callDoubleFunc(sqlite3_context *context,
|
|
int argc,
|
|
sqlite3_value **argv,
|
|
DoubleDoubleFunction f) {
|
|
double rVal = 0.0, val;
|
|
assert(argc == 1);
|
|
switch (sqlite3_value_type(argv[0])) {
|
|
case SQLITE_NULL:
|
|
sqlite3_result_null(context);
|
|
break;
|
|
default:
|
|
rVal = sqlite3_value_double(argv[0]);
|
|
errno = 0;
|
|
val = f(rVal);
|
|
if (errno == 0) {
|
|
sqlite3_result_double(context, val);
|
|
} else {
|
|
sqlite3_result_error(context, strerror(errno), errno);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void sinFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, sin);
|
|
}
|
|
|
|
static void cosFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, cos);
|
|
}
|
|
|
|
static void tanFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, tan);
|
|
}
|
|
|
|
static void asinFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, asin);
|
|
}
|
|
|
|
static void acosFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, acos);
|
|
}
|
|
|
|
static void atanFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, atan);
|
|
}
|
|
|
|
static double cot(double x) { return 1.0 / tan(x); }
|
|
|
|
static void cotFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, cot);
|
|
}
|
|
|
|
static void logFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, log);
|
|
}
|
|
|
|
static void log10Func(sqlite3_context *context,
|
|
int argc,
|
|
sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, log10);
|
|
}
|
|
|
|
static void sqrtFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, sqrt);
|
|
}
|
|
|
|
static void expFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, exp);
|
|
}
|
|
|
|
static void powerFunc(sqlite3_context *context,
|
|
int argc,
|
|
sqlite3_value **argv) {
|
|
double r1 = 0.0;
|
|
double r2 = 0.0;
|
|
double val;
|
|
|
|
assert(argc == 2);
|
|
|
|
if (sqlite3_value_type(argv[0]) == SQLITE_NULL ||
|
|
sqlite3_value_type(argv[1]) == SQLITE_NULL) {
|
|
sqlite3_result_null(context);
|
|
} else {
|
|
r1 = sqlite3_value_double(argv[0]);
|
|
r2 = sqlite3_value_double(argv[1]);
|
|
errno = 0;
|
|
val = pow(r1, r2);
|
|
if (errno == 0) {
|
|
sqlite3_result_double(context, val);
|
|
} else {
|
|
sqlite3_result_error(context, strerror(errno), errno);
|
|
}
|
|
}
|
|
}
|
|
|
|
static void callCastedDoubleFunc(sqlite3_context *context,
|
|
int argc,
|
|
sqlite3_value **argv,
|
|
DoubleDoubleFunction f) {
|
|
double rVal = 0.0;
|
|
assert(argc == 1);
|
|
switch (sqlite3_value_type(argv[0])) {
|
|
case SQLITE_INTEGER: {
|
|
int64_t iVal = sqlite3_value_int64(argv[0]);
|
|
sqlite3_result_int64(context, iVal);
|
|
break;
|
|
}
|
|
case SQLITE_NULL:
|
|
sqlite3_result_null(context);
|
|
break;
|
|
default:
|
|
rVal = sqlite3_value_double(argv[0]);
|
|
sqlite3_result_int64(context, (int64_t)f(rVal));
|
|
break;
|
|
}
|
|
}
|
|
|
|
static void ceilFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
callCastedDoubleFunc(context, argc, argv, ceil);
|
|
}
|
|
|
|
static void floorFunc(sqlite3_context *context,
|
|
int argc,
|
|
sqlite3_value **argv) {
|
|
callCastedDoubleFunc(context, argc, argv, floor);
|
|
}
|
|
|
|
/** Convert Degrees into Radians */
|
|
static double deg2rad(double x) { return x * M_PI / 180.0; }
|
|
|
|
/** Convert Radians into Degrees */
|
|
static double rad2deg(double x) { return 180.0 * x / M_PI; }
|
|
|
|
static void rad2degFunc(sqlite3_context *context,
|
|
int argc,
|
|
sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, rad2deg);
|
|
}
|
|
|
|
static void deg2radFunc(sqlite3_context *context,
|
|
int argc,
|
|
sqlite3_value **argv) {
|
|
callDoubleFunc(context, argc, argv, deg2rad);
|
|
}
|
|
|
|
static void piFunc(sqlite3_context *context, int argc, sqlite3_value **argv) {
|
|
sqlite3_result_double(context, M_PI);
|
|
}
|
|
|
|
struct FuncDef {
|
|
const char *zFunctionName;
|
|
int nArg;
|
|
void (*xFunc)(sqlite3_context *, int, sqlite3_value **);
|
|
};
|
|
|
|
void registerMathExtensions(sqlite3 *db) {
|
|
// This approach to adding non-standard Math functions was inspired by the
|
|
// somewhat deprecated/legacy work by Liam Healy from 2010 in the extension
|
|
// functions contribution.
|
|
static const struct FuncDef aFuncs[] = {
|
|
{"sqrt", 1, sqrtFunc}, {"acos", 1, acosFunc},
|
|
{"asin", 1, asinFunc}, {"atan", 1, atanFunc},
|
|
{"cos", 1, cosFunc}, {"sin", 1, sinFunc},
|
|
{"tan", 1, tanFunc}, {"cot", 1, cotFunc},
|
|
{"exp", 1, expFunc}, {"log", 1, logFunc},
|
|
{"log10", 1, log10Func}, {"power", 2, powerFunc},
|
|
{"ceil", 1, ceilFunc}, {"floor", 1, floorFunc},
|
|
{"degrees", 1, rad2degFunc}, {"radians", 1, deg2radFunc},
|
|
{"pi", 0, piFunc},
|
|
};
|
|
|
|
for (size_t i = 0; i < sizeof(aFuncs) / sizeof(struct FuncDef); i++) {
|
|
sqlite3_create_function(db, aFuncs[i].zFunctionName, aFuncs[i].nArg,
|
|
SQLITE_UTF8, nullptr, aFuncs[i].xFunc, nullptr,
|
|
nullptr);
|
|
}
|
|
}
|
|
} |