/* SPDX-License-Identifier: LGPL-3.0-or-later */

/*
 * Copyright (C) 2023 Perry Werneck <perry.werneck@gmail.com>
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published
 * by the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <https://www.gnu.org/licenses/>.
 */

 /**
  * @brief Implements string decoder.
  */

 #ifdef HAVE_CONFIG_H
	#include <config.h>
 #endif // HAVE_CONFIG_H

 #include <string>
 #include <private/decoders.h>
 #include <ctype.h>

 using namespace std;

 namespace SMBios {

	unsigned int Decoder::Worker::as_uint(const Node::Header &header, const uint8_t *smbiosdata, const size_t offset) const {
		unsigned int rc = 0;
		string str{as_string(header,smbiosdata,offset)};
		for(const char *ptr = str.c_str();*ptr && isdigit(*ptr);ptr++) {
			rc *= 10;
			rc += ('0' - *ptr);
		}
		return rc;
	}

	uint64_t Decoder::Worker::as_uint64(const Node::Header &header, const uint8_t *smbiosdata, const size_t offset) const {
		uint64_t rc = 0;
		string str{as_string(header,smbiosdata,offset)};
		for(const char *ptr = str.c_str();*ptr && isdigit(*ptr);ptr++) {
			rc *= 10;
			rc += ('0' - *ptr);
		}
		return rc;
	}

	string Decoder::Worker::as_string(const Node::Header &, const uint8_t *, const size_t) const {
		return "";
	}

	string Decoder::String::as_string(const Node::Header &header, const uint8_t *ptr, const size_t offset) const {

		if(offset > header.length) {
			return "";
		}

		uint8_t index = ptr[offset];
		if (index == 0)
			return "";

		ptr += header.length;

		while (index > 1 && *ptr) {
			ptr += strlen((const char *) ptr);
			ptr++;
			index--;
		}

		return string{(const char *) ptr};

	}

 }
