blob: ef05c70ad95f08cb2e961d5ec3460155d65a9cdc [file] [log] [blame]
// Copyright 2021 The Fuchsia Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "src/ui/input/drivers/goldfish_sensor/parser.h"
#include <cerrno>
namespace goldfish::sensor {
namespace {
std::variant<std::string, Numeric> ParseField(const std::string& field) {
// For numbers, in order to keep the precision as much as possible, we
// always try storing the data as int64_t first, otherwise we store it as
// double. Non-numbers are stored as string.
char* p = nullptr;
errno = 0;
int64_t integer = strtol(field.c_str(), &p, /*base=*/0);
if (p && *p == '\0' && errno == 0) {
return Numeric(integer);
}
errno = 0;
double num = strtod(field.c_str(), &p);
if (p && *p == '\0' && errno == 0) {
return Numeric(num);
}
return field;
}
} // namespace
SensorReport ParseSensorReport(const char* data, size_t size, size_t max_fields, char delimiter) {
SensorReport result;
std::string curr;
size_t parsed_fields = 0;
for (size_t i = 0; i <= size; i++) {
if (i < size && data[i] == '\0') {
size = i - 1;
}
if (i < size && data[i] != delimiter) {
curr += data[i];
continue;
}
if (result.name.empty()) {
result.name = std::move(curr);
} else {
result.data.push_back(ParseField(curr));
}
curr.clear();
if (max_fields > 0 && ++parsed_fields >= max_fields) {
break;
}
}
return result;
}
} // namespace goldfish::sensor