Загрузка данных


int LatticeBitParser::parseHeader()
{
	int currPos = 0;

	if (_raw_data.empty()) {
		printError("LatticeBitParser: empty bitstream");
		return EXIT_FAILURE;
	}

	const uint32_t file_size = static_cast<uint32_t>(_raw_data.size());

	/* check header signature */

	/* radiant .bit start with LSCC */
	if (_raw_data[0] == 'L') {
		if (file_size < 4) {
			printError("LatticeBitParser: bitstream too small");
			return EXIT_FAILURE;
		}
		if (_raw_data.compare(0, 4, "LSCC") != 0) {
			printf("Wrong File %s\n", _raw_data.substr(0, 4).c_str());
			return EXIT_FAILURE;
		}
		currPos += 4;
	}

	/* Check if bitstream size may store at least 0xff00 + another 0xff */
	if (file_size <= currPos + 3) {
		printError("LatticeBitParser: bitstream too small");
		return EXIT_FAILURE;
	}

	/* bit file comment area start with 0xff00 */
	if ((uint8_t)_raw_data[currPos] != 0xff ||
			(uint8_t)_raw_data[currPos + 1] != 0x00) {
		printf("Wrong File %02x%02x\n", (uint8_t) _raw_data[currPos],
			(uint8_t)_raw_data[currPos + 1]);
		return EXIT_FAILURE;
	}
	currPos += 2;

	_endHeader = _raw_data.find(0xff, currPos);
	if (_endHeader == std::string::npos) {
		printError("Error: preamble not found\n");
		return EXIT_FAILURE;
	}

	/* .bit for MACHXO3D seems to have more 0xff before preamble key */
	size_t pos = _raw_data.find(0xb3, _endHeader);
	if (pos == std::string::npos) {
		printError("Preamble key not found");
		return EXIT_FAILURE;
	}

	/* preamble must have at least 3 x 0xff + enc_key byte before 0xb3 */
	if (pos < _endHeader + 4) {
		printError("LatticeBitParser: wrong preamble size");
		return EXIT_FAILURE;
	}

	//0xbe is the key for encrypted bitstreams in Nexus fpgas
	const uint8_t enc_key = static_cast<uint8_t>(_raw_data[pos - 1]);
	if (enc_key != 0xbd && enc_key != 0xbf && enc_key != 0xbe) {
		printError("Wrong preamble key");
		return EXIT_FAILURE;
	}
	_endHeader = pos - 4; // align to 3 Dummy Bytes + preamble (ie. Header start offset).

	if (currPos >= _endHeader) {
		printError("LatticeBitParser: no header");
		return EXIT_FAILURE;
	}

	/* parse header */
	std::string_view lineStream(_raw_data.data() + currPos, _endHeader - currPos);
	while (!lineStream.empty()) {
		const size_t null_pos = lineStream.find('\0');
		const std::string_view buff = lineStream.substr(0, null_pos);
		pos = buff.find(':');
		if (pos != std::string_view::npos) {
			const std::string_view key = buff.substr(0, pos);
			const std::string_view val = buff.substr(pos + 1);
			const size_t startPos = val.find_first_not_of(' ');
			if (startPos != std::string_view::npos) {
				const size_t endPos = val.find_last_not_of(' ');
				_hdr.insert_or_assign(std::string(key),
					std::string(val.substr(startPos, endPos - startPos + 1)));
			}
		}
		if (null_pos == std::string_view::npos)
			break;
		lineStream = lineStream.substr(null_pos + 1);
	}
	return EXIT_SUCCESS;
}