/**
 * @brief VariableRecord Ctor
 * @param fileType The record type value, as found in the file.
 * @param fileHeader The file ehadewr we are associated with.
 * @param fromStream The file to read from.
 *
 */
VariableRecord::VariableRecord(RecordTypes fileType, FileHeaderRecord * fileHeader, SPSSStream &from)
	: ReadableRecord(fileType, from)
	, _pFHR(fileHeader)
{
	/*
	 * The data,
	 */
	SPSSIMPORTER_READ_MEMBER(type, from);
	SPSSIMPORTER_READ_MEMBER(has_var_label, from);
	SPSSIMPORTER_READ_MEMBER(n_missing_values, from);
	SPSSIMPORTER_READ_MEMBER(print, from);
	SPSSIMPORTER_READ_MEMBER(write, from);
	SPSSIMPORTER_READ_MEMBER(name_file, from);

	{
		const size_t numChars = sizeof(_name_file) / sizeof(char);
		char buffer[numChars + 1];
		memcpy(buffer, _name_file, numChars);
		buffer[numChars] = '\0';
		StrUtils::rTrimWSIP(buffer, numChars - 1);
		_name = buffer;
	}


	if (has_var_label() == 1)
	{
		SPSSIMPORTER_READ_MEMBER(label_len, from);
		if (label_len() > 0)
		{
			// Find the buffer size rounded up to 32 bit increments,
			size_t buffSize = roundUpTo(label_len(), 32);
			char * buffer = new char[ buffSize ];
			from.read(buffer, buffSize);
			_label.append(buffer, label_len());
			delete buffer;
		}
	}

	for (int32_t i = 0; i != abs(n_missing_values()); i++)
	{
		double val;
		from.read((char *) &val, sizeof(val)/sizeof(char));
		_missing_values.push_back(val);
	}

	_dictionary_index = fileHeader->incVarRecordCount();

}
/**
 * @brief LongVarNamesRecord Ctor
 * @param const Converters &fixer The endain fixer.
 * @param fileSubType The record subtype value, as found in the file.
 * @param fileType The record type value, as found in the file.
 * @param fromStream The file to read from.
 */
LongVarNamesRecord::LongVarNamesRecord(const NumericConverter &fixer, RecordSubTypes fileSubType, RecordTypes fileType, SPSSStream &from)
	: DataInfoRecord(fixer, fileSubType, fileType, from)
{
	char * buffer = new char[count() * size() + 2];
	from.read(buffer, count());
	_var_name_pairs.append(buffer, count());
	delete[] buffer;
}
/**
 * @brief VarDisplayParamRecord Ctor
 * @param fixer The endainness fixer.
 * @param fileSubType The record subtype value, as found in the file.
 * @param fileType The record type value, as found in the file.
 * @param fromStream The file to read from.
 */
VeryLongStringRecord::VeryLongStringRecord(const NumericConverter &fixer, RecordSubTypes fileSubType, RecordTypes fileType, SPSSStream &from)
	:DataInfoRecord(fixer, fileSubType, fileType, from)
{
	// Read string lengths.
	size_t len = size() * count();
	{
		char * buffer = new char[len + 1];
		from.read(buffer, len);
		buffer[len] = '\0';
		_string_lengths = string(buffer, len);
		delete [] buffer;
	}
}
/**
 * @brief ValueLabelRecord Ctor
 * @param const Converters &fixer - Fixes endianness.
 * @param fileType The record type value, as found in the file.
 * @param from The file to read from.
 *
 */
ValueLabelVarsRecord::ValueLabelVarsRecord(const NumericConverter &fixer, RecordTypes fileType, SPSSStream &from)
	: ReadableRecord(fixer, fileType, from)
{
	SPSSIMPORTER_READ_MEMBER(label_count, from, fixer);
	for (int32_t i = 0; i < label_count(); i++ )
	{
		// Read a single meta..
		LabelMeta meta;
		_SPSSIMPORTER_READ_VAR(meta.value, from);
		_SPSSIMPORTER_READ_VAR(meta.label_len, from);
		{
			char * buffer = new char [meta.label_len + 2];
			from.read(buffer, meta.label_len);
			fixer.fixup(buffer, meta.label_len);
			meta.label.append(buffer, meta.label_len);
			delete[] buffer;
		}
		// insert
		_Labels.push_back(meta);

		// find the following padding, by rounding up to 8 byte blocks,
		// and taking modulo
		size_t padLen = roundUpTo(sizeof(meta.label_len)+meta.label_len, 8 * 8) - (sizeof(meta.label_len)+meta.label_len);
		for (size_t j = 0; j < padLen; j++)
		{
			char padding;
			_SPSSIMPORTER_READ_VAR(padding, from);
		}
	}

	// now start in the value label record.
	SPSSIMPORTER_READ_MEMBER(var_rec_type, from, fixer);

	if (var_rec_type() != rectype_value_labels_var)
	{
//		DEBUG_COUT3("ValueLabelVarsRecord::ctor Next record not ", rectype_value_labels_var, "- File unreadable.");
		throw runtime_error("Incorrect record following a value labels record. SAV file corrupt.");
	}

	SPSSIMPORTER_READ_MEMBER(var_count, from, fixer);
	for (int i = 0; i < var_count(); i++)
	{
		int32_t indx;
		_SPSSIMPORTER_READ_VAR(indx, from);
		fixer.fixup(&indx);
		_vars.push_back(indx);
	}
}