Example #1
0
void FoxPro::setMemo(size_t record, size_t field, SeekableReadStream *value) {
	assert((record < _records.size()) && (field < _fields.size()));

	Record &r = _records[record];
	Field  &f = _fields[field];

	if (f.type != kTypeMemo)
		throw Exception("Field is not of memo type ('%c')", f.type);

	char *data = (char *) r.fields[field];

	if (!value) {
		memset(data, 0x20, f.size);
		updateUpdate();
		return;
	}

	value->seek(0);

	size_t size = value->size();

	size_t block = _memos.size();
	_memos.push_back(new byte[_memoBlockSize]);

	size_t startBlock = block + 1;

	WRITE_BE_UINT32(_memos[block]    , 1);
	WRITE_BE_UINT32(_memos[block] + 4, size);

	bool first = true;
	while (size > 0) {
		size_t n = MIN<size_t>(size, _memoBlockSize - (first ? 8 : 0));

		if (value->read(_memos[block] + (first ? 8 : 0), n) != n)
			throw Exception(kReadError);

		size  -= n;
		block += 1;

		if (size > 0)
			_memos.push_back(new byte[_memoBlockSize]);

		first = false;
	}

	if (f.decimals != 0)
		snprintf(data, f.size, "%*u", f.size, (uint) startBlock);
	else
		snprintf(data, f.size, "%*.*f", f.size, f.decimals, (double) startBlock);

	updateUpdate();
}
Example #2
0
void FoxPro::setDouble(size_t record, size_t field, double value) {
	assert((record < _records.size()) && (field < _fields.size()));

	Record &r = _records[record];
	Field  &f = _fields[field];

	char *data = (char *) r.fields[field];

	if        (f.type == kTypeNumber) {

		if (f.decimals != 0)
			snprintf(data, f.size, "%*d", f.size, (int32) value);
		else
			snprintf(data, f.size, "%*.*f", f.size, f.decimals, value);

	} else if (f.type == kTypeFloat) {

		if (f.size != 4)
			throw Exception("Float field size != 4 (%d)", f.size);

		WRITE_LE_UINT32(data, convertIEEEFloat((float) value));

	} else if (f.type == kTypeDouble) {

		if (f.size != 8)
			throw Exception("Double field size != 8 (%d)", f.size);

		WRITE_LE_UINT64(data, convertIEEEDouble(value));

	} else
		throw Exception("Field is not of double type ('%c')", f.type);

	updateUpdate();
}
Example #3
0
void FoxPro::setInt(size_t record, size_t field, int32 value) {
	assert((record < _records.size()) && (field < _fields.size()));

	Record &r = _records[record];
	Field  &f = _fields[field];

	char *data = (char *) r.fields[field];

	if        (f.type == kTypeNumber) {

		if (f.decimals != 0)
			snprintf(data, f.size, "%*d", f.size, value);
		else
			snprintf(data, f.size, "%*.*f", f.size, f.decimals, (double) value);

	} else if (f.type == kTypeInteger) {

		if (f.size != 4)
			throw Exception("Integer field size != 4 (%d)", f.size);

		WRITE_LE_UINT32(data, value);

	} else
		throw Exception("Field is not of int type ('%c')", f.type);

	updateUpdate();
}
Example #4
0
size_t FoxPro::addFieldMemo(const UString &name) {
	size_t offset = 1;
	if (!_fields.empty())
		offset = _fields.back().offset + _fields.back().size;

	_fields.push_back(Field());

	Field &field = _fields.back();

	field.name        = name;
	field.type        = kTypeMemo;
	field.offset      = offset;
	field.size        = 10;
	field.decimals    = 0;
	field.flags       = 0;
	field.autoIncNext = 0;
	field.autoIncStep = 0;

	addField(field.size);
	updateUpdate();

	_hasMemo = true;

	return _fields.size() - 1;
}
Example #5
0
void FoxPro::deleteRecord(size_t record) {
	assert(record < _records.size());

	_records[record].deleted = true;

	updateUpdate();

	// TODO: Deleting a record should also mark any memo fields in that
	//       record as free. They should be reused when adding a memo
	//       field of equals or less size.
}
Example #6
0
void FoxPro::setDate(size_t record, size_t field, uint16 year, uint8 month, uint8 day) {
	assert((record < _records.size()) && (field < _fields.size()));

	Record &r = _records[record];
	Field  &f = _fields[field];

	if (f.type != kTypeDate)
		throw Exception("Field is not of date type ('%c')", f.type);

	char *data = reinterpret_cast<char *>(r.fields[field]);

	snprintf(data, 8, "%04u%02u%02u", (uint) year, (uint) month, (uint) day);

	updateUpdate();
}
Example #7
0
void FoxPro::setDate(size_t record, size_t field, const date &value) {
	assert((record < _records.size()) && (field < _fields.size()));

	Record &r = _records[record];
	Field  &f = _fields[field];

	if (f.type != kTypeDate)
		throw Exception("Field is not of date type ('%c')", f.type);

	char *data = (char *) r.fields[field];

	snprintf(data, 8, "%04d%02d%02d",
			(int) value.year(), (int) value.month(), (int) value.day());

	updateUpdate();
}
Example #8
0
void FoxPro::setBool(size_t record, size_t field, bool value) {
	assert((record < _records.size()) && (field < _fields.size()));

	Record &r = _records[record];
	Field  &f = _fields[field];

	if (f.type != kTypeBool)
		throw Exception("Field is not of bool type ('%c')", f.type);

	if (f.size != 1)
		throw Exception("Bool field size != 1 (%d)", f.size);

	char *data = (char *) r.fields[field];

	data[0] = value ? 'T' : 'F';

	updateUpdate();
}
Example #9
0
void FoxPro::setString(size_t record, size_t field, const UString &value) {
	assert((record < _records.size()) && (field < _fields.size()));

	Record &r = _records[record];
	Field  &f = _fields[field];

	if (f.type != kTypeString)
		throw Exception("Field is not of string type ('%c')", f.type);

	char *data    = (char *) r.fields[field];
	char *dataEnd = (char *) r.fields[field] + f.size;

	strncpy(data, value.c_str(), f.size);

	data += strlen(value.c_str());

	while (data < dataEnd)
		*dataEnd++ = 0x20;

	updateUpdate();
}
Example #10
0
size_t FoxPro::addFieldNumber(const UString &name, uint8 size, uint8 decimals) {
	size_t offset = 1;
	if (!_fields.empty())
		offset = _fields.back().offset + _fields.back().size;

	_fields.push_back(Field());

	Field &field = _fields.back();

	field.name        = name;
	field.type        = kTypeNumber;
	field.offset      = offset;
	field.size        = size;
	field.decimals    = decimals;
	field.flags       = 0;
	field.autoIncNext = 0;
	field.autoIncStep = 0;

	addField(field.size);
	updateUpdate();

	return _fields.size() - 1;
}
Example #11
0
size_t FoxPro::addRecord() {
	_records.push_back(Record());
	Record &record = _records.back();

	record.deleted = false;

	if (!_fields.empty()) {
		size_t dataSize = _fields.back().offset + _fields.back().size;

		_pool.push_back(new byte[dataSize]);

		byte *data = _pool.back();

		record.fields.resize(_fields.size());
		for (size_t i = 0; i < _fields.size(); i++) {
			record.fields[i] = data;
			data += _fields[i].size;
		}
	}

	updateUpdate();

	return _records.size() - 1;
}
Example #12
0
FoxPro::FoxPro() : _hasIndex(false), _hasMemo(false), _memoBlockSize(512) {
	updateUpdate();
}