Esempio n. 1
0
// TODO: Allow us to read an XML file from stdin
bool HaggleKernel::readStartupDataObject(FILE *fp)
{
	long len;
	ssize_t	k;
	size_t i, j, items, total_bytes_read = 0;
	char *data;
	bool ret = false;
	
	if (!fp) {
		HAGGLE_ERR("Invalid file pointer\n");
		return false;
	}
	// Figure out how large the file is.
	fseek(fp, 0, SEEK_END);
	// No, this does not handle files larger than 2^31 bytes, but that 
	// shouldn't be a problem, and could be easily fixed if necessary.
	len = ftell(fp);
	fseek(fp, 0, SEEK_SET);
	
	// Allocate space to put the data in. +1 byte 
	// so that we make sure we read until EOF in 
	// the read loop.
	data = new char[++len];
	
	if (!data) {
		HAGGLE_ERR("Could not allocate data\n");
		return false;
	}
	// Read the data:
	do {
		items = fread(data + total_bytes_read, 1, len - total_bytes_read, fp);
		total_bytes_read += items;
	} while (items != 0 && total_bytes_read < (size_t)len);

	if (ferror(fp) != 0) {
		HAGGLE_ERR("File error when reading configuration\n");
		goto out;
	}

	// Check that we reached EOF
	if (feof(fp) != 0) {
		DataObject *dObj = NULL;
	
		// Success! Now create data object(s):
		i = 0;
		
		while (i < total_bytes_read) {
			if (!dObj)
				dObj = DataObject::create_for_putting();
			
			if (!dObj) {
				HAGGLE_ERR("Could not create data object for putting\n");
				ret = false;
				goto out;
			}

			k = dObj->putData(&(data[i]), total_bytes_read - i, &j);
			
			// Check return value:
			if (k < 0) {
				// Error occured, stop everything:
				HAGGLE_ERR("Error parsing startup data object "
					   "(byte %ld of %ld)\n", i, total_bytes_read);
				i = total_bytes_read;
			} else {
				// No error, check if we're done:
				if (k == 0 || j == 0) {
					// Done with this data object:
#ifdef DEBUG
				        dObj->print(NULL); // MOS - NULL means print to debug trace
#endif
					addEvent(new Event(EVENT_TYPE_DATAOBJECT_RECEIVED, DataObjectRef(dObj)));
					// Should absolutely not deallocate this, since it 
					// is in the event queue:
					dObj = NULL;
					// These bytes have been consumed:
					i += k;
					ret = true;
				} else if (k > 0) {
					// These bytes have been consumed:
					i += k;
				}
			}
		}
		// Clean up:
		if (dObj) {
			delete dObj;
		}
	}
out:
	delete [] data;
	
	return ret;
}