Exemple #1
0
DCMsg::MessageClosureEnum
DCMsg::messageReceived( DCMessenger *messenger, Sock *)
{
	reportSuccess( messenger );

	return MESSAGE_FINISHED;
}
void ConnectedThresholdImageFilter::postProcessingSlot()
{
	//get the result from the thread
	vtkImageDataPtr rawResult = this->getResult();

	if(!rawResult)
	{
		reportError("Segmentation failed.");
		return;
	}

	//generate a new name and unique id for the newly created object
	QString uid = mInput->getUid() + "_seg%1";
	QString name = mInput->getName()+" seg%1";

	//create a Image
	ImagePtr result = createDerivedImage(mServices->patient(),
										 uid, name,
										 rawResult, mInput);
	mOutput->resetTransferFunctions();

	mServices->patient()->insertData(mOutput);

	//let the user know you are finished
	reportSuccess("Done segmenting: \"" + mOutput->getName()+"\"");

	//let the system know you're finished
	//  emit finished();
}
Exemple #3
0
void USSavingRecorder::startRecord(RecordSessionPtr session, ToolPtr tool, ToolPtr reference, std::vector<VideoSourcePtr> video)
{
	this->clearRecording(); // clear previous data if any

	mRecordingTool = tool;
	mReference = reference;
	mSession = session;

	QString tempBaseFolder = DataLocations::getCachePath()+"/usacq/"+QDateTime::currentDateTime().toString(timestampSecondsFormat());
	QString cacheFolder = UsReconstructionFileMaker::createUniqueFolder(tempBaseFolder, session->getDescription());

	for (unsigned i=0; i<video.size(); ++i)
	{
		SavingVideoRecorderPtr videoRecorder;
		videoRecorder.reset(new SavingVideoRecorder(
								 video[i],
								 cacheFolder,
								 QString("%1_%2").arg(session->getDescription()).arg(video[i]->getUid()),
								 false, // no compression when saving to cache
								 mDoWriteColor));
		videoRecorder->startRecord();
		mVideoRecorder.push_back(videoRecorder);
	}

	reportSuccess("Ultrasound acquisition started.");
}
Exemple #4
0
void AbstractCommand::setSocket(QTcpSocket* socket) 
{
    debugOutput(0, "AbstractCommand::setSocket()");
    Q_ASSERT(socket);
    m_socket = socket;
    connect(m_socket, SIGNAL(readyRead()), this, SLOT(_readData()));
    reportSuccess();
}
void ProcessReporter::processFinished(int exitCode, QProcess::ExitStatus exitStatus)
{
	QString msg = QString("%1 exited with exit status %3. (%1 last exit code was %4.)").arg(mName).arg(exitStatus).arg(exitCode);
	if(exitStatus == 0)
		reportSuccess(msg);
	else
		reportError(msg);
}
void TrackingSystemIGSTKService::trackerTrackingSlot(bool value)
{
	if (value)
	{
		mState = Tool::tsTRACKING;
		reportSuccess("IGSTK Tracking Service started tracking.");
		emit stateChanged();
		emit trackingStarted();
	}
	else
	{
		mState = Tool::tsINITIALIZED;
		reportSuccess("IGSTK Tracking Service stopped tracking.");
		emit stateChanged();
		emit trackingStopped();
	}
}
Exemple #7
0
void CopyDirectoryCommand::dataReceived(QByteArray &data)
{
    debugOutput(0, "CopyDirectoryCommand::dataReceived()");
    CopyDirectoryOptions* options = (CopyDirectoryOptions*) data.data();
    debugOutput(3, QString::fromLatin1("Copy Directory: %1 %2").arg(options->from).arg(options->to));
    if (copyDir(QLatin1String(options->from) , QLatin1String(options->to) , options->recursive))
        reportSuccess();
    else
        reportError();
}
void RegistrationImplService::applyPatientRegistration(Transform3D rMpr_new, QString description)
{
	RegistrationTransform regTrans(rMpr_new, QDateTime::currentDateTime(), description);
	regTrans.mFixed = mFixedData;

	mPatientModelService->updateRegistration_rMpr(mLastRegistrationTime, regTrans);

	mLastRegistrationTime = regTrans.mTimestamp;
	reportSuccess(QString("Patient registration [%1] has been performed.").arg(description));
}
void RegistrationImplService::applyImage2ImageRegistration(Transform3D delta_pre_rMd, QString description)
{
	RegistrationTransform regTrans(delta_pre_rMd, QDateTime::currentDateTime(), description);
	regTrans.mFixed = mFixedData;
	regTrans.mMoving = mMovingData;

	this->updateRegistration(mLastRegistrationTime, regTrans, this->getMovingData());

	mLastRegistrationTime = regTrans.mTimestamp;
	reportSuccess(QString("Image registration [%1] has been performed on %2").arg(description).arg(regTrans.mMoving) );
}
Exemple #10
0
void USSavingRecorder::stopRecord()
{
	for (unsigned i=0; i<mVideoRecorder.size(); ++i)
		mVideoRecorder[i]->stopRecord();
	reportSuccess("Ultrasound acquisition stopped.");

	for (unsigned i=0; i<mVideoRecorder.size(); ++i)
	{
		// complete writing of images to temporary storage. Do this before using the image data.
		mVideoRecorder[i]->completeSave();
	}
}
Exemple #11
0
void owperGUI::applyChanges(string successMessage, owperGUI *thisOwperGUI) {
    if(!thisOwperGUI->sam->mergeChangesToHive()) {
        reportMergeFailure(thisOwperGUI);
        return;
    }

    if(!thisOwperGUI->sam->writeHiveToFile()) {
        reportSaveFailure(thisOwperGUI);
        return;
    }

    reportSuccess(successMessage, thisOwperGUI);
}
void TrackingSystemIGSTKService::initializedSlot(bool value)
{
	if (value)
	{
		mState = Tool::tsINITIALIZED;
		reportSuccess("IGSTK Tracking Service is initialized.");
		emit stateChanged();
		emit initialized();
	}
	else
	{
		mState = Tool::tsCONFIGURED;
		report("IGSTK Tracking Service is uninitialized.");
		emit stateChanged();
		emit uninitialized();
	}
}
Exemple #13
0
void CreateDirectoryCommand::dataReceived(QByteArray &data)
{
    debugOutput(0, "CreateDirectoryCommand::dataReceived()");
    CreateDirectoryOptions* options = (CreateDirectoryOptions*) data.data();
    debugOutput(3, QString::fromLatin1("Creating directory: %1").arg(options->dirName));
    bool success = true;
    QDir dir;
    if (options->recursively)
        success = dir.mkpath(options->dirName);
    else
        success = dir.mkdir(options->dirName);
    
    if (success)
        reportSuccess();
    else
        reportError();
}
/**\brief Identical to doFastRegistration_Orientation(), except data does not move.
 *
 * When applying a new transform to the patient orientation, all data is moved
 * the the inverse of that value, thus giving a net zero change along the path
 * pr...d_i.
 *
 */
void RegistrationImplService::applyPatientOrientation(const Transform3D& tMtm, const Transform3D& prMt)
{
	Transform3D rMpr = mPatientModelService->get_rMpr();

	//create a marked(m) space tm, which is related to tool space (t) as follows:
	//the tool is defined in DICOM space such that
	//the tool points toward the patients feet and the spheres faces the same
	//direction as the nose
	Transform3D tMpr = prMt.inv();

	// this is the new patient registration:
	Transform3D tmMpr = tMtm * tMpr;
	// the change in pat reg becomes:
	Transform3D F = tmMpr * rMpr.inv();

	QString description("Patient Orientation");

	QDateTime oldTime = this->getLastRegistrationTime(); // time of previous reg
	this->applyPatientRegistration(tmMpr, description);

	// now apply the inverse of F to all data,
	// thus ensuring the total path from pr to d_i is unchanged:
	Transform3D delta_pre_rMd = F;


	// use the same registration time as generated in the applyPatientRegistration() above:
	RegistrationTransform regTrans(delta_pre_rMd, this->getLastRegistrationTime(), description);

	std::map<QString,DataPtr> data = mPatientModelService->getData();
	// update the transform on all target data:
	for (std::map<QString,DataPtr>::iterator iter = data.begin(); iter!=data.end(); ++iter)
	{
		DataPtr current = iter->second;
		RegistrationTransform newTransform = regTrans;
		newTransform.mValue = regTrans.mValue * current->get_rMd();
		current->get_rMd_History()->updateRegistration(oldTime, newTransform);

		report("Updated registration of data " + current->getName());
		std::cout << "rMd_new\n" << newTransform.mValue << std::endl;
	}

	this->setLastRegistrationTime(regTrans.mTimestamp);

	reportSuccess("Patient Orientation has been performed");
}
Exemple #15
0
void CopyFileCommand::dataReceived(QByteArray &data)
{
    debugOutput(0, "CopyFileCommand::dataReceived()");
    CopyFileOptions* options = (CopyFileOptions*) data.data();
    debugOutput(3, QString::fromLatin1("Copy File: %1 ->  %2").arg(options->from).arg(options->to));
    bool success = true;
    if (QFileInfo(options->to).exists()) {
        if (options->overwriteExisting)
            QFile::remove(options->to);
        else
            success = false;
    }
    if (success)
        if (!QFile::copy(options->from , options->to))
            success = false;
    
    if (success)
        reportSuccess();
    else
        reportError();
}
void TrackingSystemIGSTKService::trackerConfiguredSlot(bool on)
{
	if (!on)
	{
		this->deconfigure();
		return;
	}

	if (!mTrackerThread)
	{
		reportDebug("Received a configured signal in ToolManager, but we don't have a mTrackerThread, this should never happen, contact programmer.");
		return;
	}

	//new all tools
	mTools.clear();
	std::map<QString, IgstkToolPtr> igstkTools = mTrackerThread->getTools();
	IgstkToolPtr reference = mTrackerThread->getRefereceTool();
	std::map<QString, IgstkToolPtr>::iterator it = igstkTools.begin();
	for (; it != igstkTools.end(); ++it)
	{
		IgstkToolPtr igstkTool = it->second;
		cxToolPtr tool(new ToolUsingIGSTK(igstkTool));
		if (tool->isValid())
		{
			mTools.push_back(tool);
			if (tool->getProbe())
				emit newProbe(tool);
		}
		else
			reportWarning("Creation of the cxTool " + it->second->getUid() + " failed.");
	}

	mState = Tool::tsCONFIGURED;

	reportSuccess("IGSTK Tracking Service Configured.");
	emit configured();
	emit stateChanged();
}
Exemple #17
0
void CreateFileCommand::dataReceived(QByteArray &data)
{
    bool successful = true;
    // If we haven't received the options yet
    if (m_options.fileSize == -1) {
        CreateFileOptions* opt = (CreateFileOptions*) data.data();
        memcpy(&m_options , opt , sizeof(CreateFileOptions));

        if (QFileInfo(QString::fromLatin1(m_options.fileName)).exists()) {
            if (m_options.overwriteExisting) {
#ifdef Q_OS_WINCE
                SetFileAttributes(QFileInfo(m_options.fileName).absoluteFilePath().utf16(), FILE_ATTRIBUTE_NORMAL);
#endif
                QFile::remove(m_options.fileName);
            } else
                successful = false;
        }
        m_file.setFileName(QString::fromLatin1(m_options.fileName));
        if (!m_file.open(QIODevice::WriteOnly))
            successful = false;
        else
            debugOutput(3, QString::fromLatin1("Creating file: %1").arg(m_options.fileName));
    } else { // write buffer on disc
        if (!m_file.isOpen())
            return;
        m_file.write(data);
        m_dataCount += data.size();
        if (m_dataCount >= m_options.fileSize) {
            // We do not care about more data than announced
            m_file.close();
        }
    }
    
    if (successful)
        reportSuccess();
    else
        reportError();
}
/** Call nearly all wallet functions and make sure they
  * return #WALLET_NOT_THERE somehow. This should only be called if a wallet
  * is not loaded. */
static void checkFunctionsReturnWalletNotThere(void)
{
	uint8_t temp[128];
	uint32_t check_num_addresses;
	AddressHandle ah;
	PointAffine public_key;

	// newWallet() not tested because it calls initWallet() when it's done.
	ah = makeNewAddress(temp, &public_key);
	if ((ah == BAD_ADDRESS_HANDLE) && (walletGetLastError() == WALLET_NOT_THERE))
	{
		reportSuccess();
	}
	else
	{
		printf("makeNewAddress() doesn't recognise when wallet isn't there\n");
		reportFailure();
	}
	check_num_addresses = getNumAddresses();
	if ((check_num_addresses == 0) && (walletGetLastError() == WALLET_NOT_THERE))
	{
		reportSuccess();
	}
	else
	{
		printf("getNumAddresses() doesn't recognise when wallet isn't there\n");
		reportFailure();
	}
	if (getAddressAndPublicKey(temp, &public_key, 0) == WALLET_NOT_THERE)
	{
		reportSuccess();
	}
	else
	{
		printf("getAddressAndPublicKey() doesn't recognise when wallet isn't there\n");
		reportFailure();
	}
	if (getPrivateKey(temp, 0) == WALLET_NOT_THERE)
	{
		reportSuccess();
	}
	else
	{
		printf("getPrivateKey() doesn't recognise when wallet isn't there\n");
		reportFailure();
	}
	if (changeEncryptionKey(temp) == WALLET_NOT_THERE)
	{
		reportSuccess();
	}
	else
	{
		printf("changeEncryptionKey() doesn't recognise when wallet isn't there\n");
		reportFailure();
	}
	if (changeWalletName(temp) == WALLET_NOT_THERE)
	{
		reportSuccess();
	}
	else
	{
		printf("changeWalletName() doesn't recognise when wallet isn't there\n");
		reportFailure();
	}
}
Exemple #19
0
void OSGConverter::process(const SendRequest& req) {

//  std::cout << req;

	int width = 640;
	int height = 480;
	Event::getParam(req.params, "width", width);
	Event::getParam(req.params, "height", height);

	assert(req.params.find("source") != req.params.end());
	assert(req.params.find("format") != req.params.end());

	std::string source;
	if (!Event::getParam(req.params, "source", source))
		reportFailure(req);

	std::string dest;
	Event::getParam(req.params, "dest", dest);

	std::string format;
	if (!Event::getParam(req.params, "format", format))
		reportFailure(req);

	bool autoRotate = true;
	if (req.params.find("autorotate") != req.params.end()) {
		if (iequals(req.params.find("autorotate")->second.atom, "off") ||
		        iequals(req.params.find("autorotate")->second.atom, "0") ||
		        iequals(req.params.find("autorotate")->second.atom, "false")) {
			autoRotate = false;
		}
	}

	osg::ref_ptr<osg::Node> model = setupGraph(source, autoRotate);
	if (model->asGroup()->getNumChildren() == 0) {
		reportFailure(req);
		return;
	}

	osg::ref_ptr<osg::Group> sceneGraph = new osg::Group();
	sceneGraph->addChild(model);

	osgDB::ReaderWriter::WriteResult result;

	osg::ref_ptr<osgDB::ReaderWriter> writer = osgDB::Registry::instance()->getReaderWriterForExtension(format);
	if(writer.valid()) {
		std::stringstream ss;
		result = writer->writeNode(*sceneGraph, ss);
		if (result.success()) {
			if (dest.length() > 0) {
				std::ofstream outFile(dest.c_str());
				outFile << ss.str();
			}
			Data content(ss.str().c_str(), ss.str().size(), URL::getMimeType(format), false);
			reportSuccess(req, content);
			return;
		}
	}

	/**
	 * If we failed to interpret the extension as another 3D file, try to make a screenshot.
	 */

	((osg::MatrixTransform*)model.get())->setMatrix(requestToModelPose(req));
	osg::BoundingSphere bs = model->getBound();

//  osg::ref_ptr<osg::MatrixTransform> scale = new osg::MatrixTransform();
//  scale->setMatrix(osg::Matrix::scale(bs.radius() / 5, bs.radius() / 5, bs.radius() / 5));
//  scale->addChild(getOrigin());
//  sceneGraph->addChild(scale);

	osgViewer::ScreenCaptureHandler::CaptureOperation* cOp = new NameRespectingWriteToFile(
	    dest,
	    format,
	    osgViewer::ScreenCaptureHandler::WriteToFile::OVERWRITE,
	    req, this);

	osgViewer::ScreenCaptureHandler* captureHandler = new osgViewer::ScreenCaptureHandler(cOp, -1);

	{
		tthread::lock_guard<tthread::recursive_mutex> lock(_viewerMutex);
		osgViewer::Viewer viewer;
		osg::ref_ptr<osg::GraphicsContext> gc;

		viewer.setSceneData(sceneGraph);
		viewer.addEventHandler(captureHandler);
		captureHandler->startCapture();

		osg::DisplaySettings* ds = osg::DisplaySettings::instance().get();
		osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits(ds);
		traits->width = width;
		traits->height = height;
		// this fails with ubuntu in a VM in parallels
		traits->pbuffer = true;

		gc = osg::GraphicsContext::createGraphicsContext(traits.get());

		if (!gc.valid()) {
			LOG(ERROR) << "Cannot create GraphicsContext!";
			return;
		}

		if (!traits->width || !traits->height) {
			LOG(ERROR) << "Traits returned with zero dimensions";
			return;
		}

		GLenum pbuffer = gc->getTraits()->doubleBuffer ? GL_BACK : GL_FRONT;

		viewer.setCameraManipulator(new osgGA::TrackballManipulator());
		viewer.getCamera()->setGraphicsContext(gc.get());
		viewer.getCamera()->setViewport(new osg::Viewport(0,0,traits->width,traits->height));
		viewer.getCamera()->setDrawBuffer(pbuffer);
		viewer.getCamera()->setReadBuffer(pbuffer);

		double zoom = 1;
		CAST_PARAM(req.params, zoom, "zoom", double);

		// set background color
		viewer.getCamera()->setClearColor(osg::Vec4f(1.0f,1.0f,1.0f,1.0f));
		viewer.getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
		viewer.getCameraManipulator()->setByMatrix(osg::Matrix::lookAt(osg::Vec3d(0,0,bs.radius() * (-3.4 * zoom)),  // eye
		        (osg::Vec3d)bs.center(),           // center
		        osg::Vec3d(0,1,0)));               // up

		//  viewer.home();

		// perform one viewer iteration
		viewer.realize();
		viewer.frame();

		viewer.removeEventHandler(captureHandler);
	}

//	delete(cOp);
//	delete(captureHandler);
}
/** A proper test suite for randomness would be quite big, so this test
  * spits out samples into random.dat, where they can be analysed using
  * an external program.
  */
int main(int argc, char **argv)
{
	uint8_t r[32];
	int i, j;
	int num_samples;
	int abort;
	unsigned int bytes_written;
	FILE *f;
	uint8_t seed[64];
	uint8_t keys[64][32];
	uint8_t key2[32];

	initTests(__FILE__);

	// Before outputting samples, do a sanity check that
	// generateDeterministic256() actually has different outputs when
	// each byte of the seed is changed.
	abort = 0;
	for (i = 0; i < 64; i++)
	{
		memset(seed, 0, 64);
		seed[i] = 1;
		generateDeterministic256(keys[i], seed, 0);
		for (j = 0; j < i; j++)
		{
			if (bigCompare(keys[i], keys[j]) == BIGCMP_EQUAL)
			{
				printf("generateDeterministic256() is ignoring byte %d of seed\n", i);
				abort = 1;
				break;
			}
		}
		if (abort)
		{
			break;
		}
	}
	if (abort)
	{
		reportFailure();
	}
	else
	{
		reportSuccess();
	}

	// Check that generateDeterministic256() isn't ignoring num.
	memset(seed, 0, 64);
	seed[0] = 1;
	generateDeterministic256(key2, seed, 1);
	abort = 0;
	for (j = 0; j < 64; j++)
	{
		if (bigCompare(key2, keys[j]) == BIGCMP_EQUAL)
		{
			printf("generateDeterministic256() is ignoring num\n");
			abort = 1;
			break;
		}
	}
	if (abort)
	{
		reportFailure();
	}
	else
	{
		reportSuccess();
	}

	// Check that generateDeterministic256() is actually deterministic.
	generateDeterministic256(key2, seed, 0);
	if (bigCompare(key2, keys[0]) != BIGCMP_EQUAL)
	{
		printf("generateDeterministic256() is not deterministic\n");
		reportFailure();
	}
	else
	{
		reportSuccess();
	}

	if (argc != 2)
	{
		printf("Usage: %s <n>, where <n> is number of 256 bit samples to take\n", argv[0]);
		printf("Samples will go into random.dat\n");
		exit(1);
	}
	sscanf(argv[1], "%d", &num_samples);
	if (num_samples <= 0)
	{
		printf("Invalid number of samples specified\n");
		exit(1);
	}

	f = fopen("random.dat", "wb");
	if (f == NULL)
	{
		printf("Could not open random.dat for writing\n");
		exit(1);
	}
	srand(42);
	bytes_written = 0;
	for (i = 0; i < num_samples; i++)
	{
		getRandom256(r);
		bytes_written += fwrite(r, 1, 32, f);
	}
	fclose(f);

	printf("%u bytes written to random.dat\n", bytes_written);
	finishTests();

	exit(0);
}
Exemple #21
0
	foreach(QString string, mReport)
	{
		reportSuccess(string);
	}
Exemple #22
0
bool
PointAttenuationTest::testPointRendering(GLboolean smooth)
{
	// epsilon is the allowed size difference in pixels between the
	// expected and actual rendering.
	const GLfloat epsilon = (smooth ? 1.5 : 1.0) + 0.0;
	GLfloat atten[3];
	int count = 0;

	// Enable front buffer if you want to see the rendering
	glDrawBuffer(GL_FRONT);
	glReadBuffer(GL_FRONT);

	if (smooth) {
		glEnable(GL_POINT_SMOOTH);
		glEnable(GL_BLEND);
		glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	}
	else {
		glDisable(GL_POINT_SMOOTH);
		glDisable(GL_BLEND);
	}

	for (int a = 0; a < 3; a++) {
		atten[0] = pow(10.0, -a);
		for (int b = -2; b < 3; b++) {
			atten[1] = (b == -1) ? 0.0 : pow(10.0, -b);
			for (int c = -2; c < 3; c++) {
				atten[2] = (c == -1) ? 0.0 : pow(10.0, -c);
				PointParameterfvARB(GL_POINT_DISTANCE_ATTENUATION_ARB, atten);
				for (float min = 1.0; min < MAX_SIZE; min += 10) {
					PointParameterfARB(GL_POINT_SIZE_MIN_ARB, min);
					for (float max = min; max < MAX_SIZE; max += 10) {
						PointParameterfARB(GL_POINT_SIZE_MAX_ARB, max);
						for (float size = 1.0; size < MAX_SIZE; size += 8) {
							glPointSize(size);

							// draw column of points
							glClear(GL_COLOR_BUFFER_BIT);
							glBegin(GL_POINTS);
							for (float z = -6.0; z <= 6.0; z += 1.0) {
								glVertex3f(0, z, z);
							}
							glEnd();

							// test the column of points
							for (float z = -6.0; z <= 6.0; z += 1.0) {
								count++;
								float expected
									= expectedSize(size, atten, min, max,
												   z, smooth);
								float actual = measureSize(z);
								if (fabs(expected - actual) > epsilon) {
									reportFailure(size, atten, min, max,
												  z, smooth,
												  expected, actual);
									return false;
								}
								else if(0){
									printf("pass z=%f exp=%f act=%f\n",
										   z, expected, actual);
								}
							}
						}
					}
				}
			}
		}
	}
	reportSuccess(count, smooth);
	return true;
}
int main(void)
{
	uint8_t temp[128];
	uint8_t address1[20];
	uint8_t address2[20];
	uint8_t name[NAME_LENGTH];
	uint8_t encryption_key[WALLET_ENCRYPTION_KEY_LENGTH];
	uint8_t new_encryption_key[WALLET_ENCRYPTION_KEY_LENGTH];
	uint8_t version[4];
	uint8_t *address_buffer;
	uint8_t one_byte;
	AddressHandle *handles_buffer;
	AddressHandle ah;
	PointAffine public_key;
	PointAffine *public_key_buffer;
	int abort;
	int is_zero;
	int abort_duplicate;
	int abort_error;
	int i;
	int j;

	initTests(__FILE__);

	initWalletTest();
	memset(encryption_key, 0, WALLET_ENCRYPTION_KEY_LENGTH);
	setEncryptionKey(encryption_key);
	// Blank out non-volatile storage area (set to all nulls).
	temp[0] = 0;
	for (i = 0; i < TEST_FILE_SIZE; i++)
	{
		fwrite(temp, 1, 1, wallet_test_file);
	}

	// sanitiseNonVolatileStorage() should nuke everything.
	if (sanitiseNonVolatileStorage(0, 0xffffffff) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("Cannot nuke NV storage using sanitiseNonVolatileStorage()\n");
		reportFailure();
	}

	// Check that the version field is "wallet not there".
	if (getWalletInfo(version, temp) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() failed after sanitiseNonVolatileStorage() was called\n");
		reportFailure();
	}
	if (readU32LittleEndian(version) == VERSION_NOTHING_THERE)
	{
		reportSuccess();
	}
	else
	{
		printf("sanitiseNonVolatileStorage() does not set version to nothing there\n");
		reportFailure();
	}

	// initWallet() hasn't been called yet, so nearly every function should
	// return WALLET_NOT_THERE somehow.
	checkFunctionsReturnWalletNotThere();

	// The non-volatile storage area was blanked out, so there shouldn't be a
	// (valid) wallet there.
	if (initWallet() == WALLET_NOT_THERE)
	{
		reportSuccess();
	}
	else
	{
		printf("initWallet() doesn't recognise when wallet isn't there\n");
		reportFailure();
	}

	// Try creating a wallet and testing initWallet() on it.
	memcpy(name, "123456789012345678901234567890abcdefghij", NAME_LENGTH);
	if (newWallet(name) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("Could not create new wallet\n");
		reportFailure();
	}
	if (initWallet() == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("initWallet() does not recognise new wallet\n");
		reportFailure();
	}
	if ((getNumAddresses() == 0) && (walletGetLastError() == WALLET_EMPTY))
	{
		reportSuccess();
	}
	else
	{
		printf("New wallet isn't empty\n");
		reportFailure();
	}

	// Check that the version field is "unencrypted wallet".
	if (getWalletInfo(version, temp) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() failed after newWallet() was called\n");
		reportFailure();
	}
	if (readU32LittleEndian(version) == VERSION_UNENCRYPTED)
	{
		reportSuccess();
	}
	else
	{
		printf("newWallet() does not set version to unencrypted wallet\n");
		reportFailure();
	}

	// Check that sanitise_nv_wallet() deletes wallet.
	if (sanitiseNonVolatileStorage(0, 0xffffffff) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("Cannot nuke NV storage using sanitiseNonVolatileStorage()\n");
		reportFailure();
	}
	if (initWallet() == WALLET_NOT_THERE)
	{
		reportSuccess();
	}
	else
	{
		printf("sanitiseNonVolatileStorage() isn't deleting wallet\n");
		reportFailure();
	}

	// Make some new addresses, then create a new wallet and make sure the
	// new wallet is empty (i.e. check that newWallet() deletes existing
	// wallet).
	newWallet(name);
	if (makeNewAddress(temp, &public_key) != BAD_ADDRESS_HANDLE)
	{
		reportSuccess();
	}
	else
	{
		printf("Couldn't create new address in new wallet\n");
		reportFailure();
	}
	newWallet(name);
	if ((getNumAddresses() == 0) && (walletGetLastError() == WALLET_EMPTY))
	{
		reportSuccess();
	}
	else
	{
		printf("newWallet() doesn't delete existing wallet\n");
		reportFailure();
	}

	// Unload wallet and make sure everything realises that the wallet is
	// not loaded.
	if (uninitWallet() == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("uninitWallet() failed to do its basic job\n");
		reportFailure();
	}
	checkFunctionsReturnWalletNotThere();

	// Load wallet again. Since there is actually a wallet there, this
	// should succeed.
	if (initWallet() == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("uninitWallet() appears to be permanent\n");
		reportFailure();
	}

	// Change bytes in non-volatile memory and make sure initWallet() fails
	// because of the checksum check.
	if (uninitWallet() != WALLET_NO_ERROR)
	{
		printf("uninitWallet() failed to do its basic job 2\n");
		reportFailure();
	}
	abort = 0;
	for (i = 0; i < WALLET_RECORD_LENGTH; i++)
	{
		if (nonVolatileRead(&one_byte, (uint32_t)i, 1) != NV_NO_ERROR)
		{
			printf("NV read fail\n");
			abort = 1;
			break;
		}
		one_byte++;
		if (nonVolatileWrite(&one_byte, (uint32_t)i, 1) != NV_NO_ERROR)
		{
			printf("NV write fail\n");
			abort = 1;
			break;
		}
		if (initWallet() == WALLET_NO_ERROR)
		{
			printf("Wallet still loads when wallet checksum is wrong, offset = %d\n", i);
			abort = 1;
			break;
		}
		one_byte--;
		if (nonVolatileWrite(&one_byte, (uint32_t)i, 1) != NV_NO_ERROR)
		{
			printf("NV write fail\n");
			abort = 1;
			break;
		}
	}
	if (!abort)
	{
		reportSuccess();
	}
	else
	{
		reportFailure();
	}

	// Create 2 new wallets and check that their addresses aren't the same
	newWallet(name);
	if (makeNewAddress(address1, &public_key) != BAD_ADDRESS_HANDLE)
	{
		reportSuccess();
	}
	else
	{
		printf("Couldn't create new address in new wallet\n");
		reportFailure();
	}
	newWallet(name);
	memset(address2, 0, 20);
	memset(&public_key, 0, sizeof(PointAffine));
	if (makeNewAddress(address2, &public_key) != BAD_ADDRESS_HANDLE)
	{
		reportSuccess();
	}
	else
	{
		printf("Couldn't create new address in new wallet\n");
		reportFailure();
	}
	if (memcmp(address1, address2, 20))
	{
		reportSuccess();
	}
	else
	{
		printf("New wallets are creating identical addresses\n");
		reportFailure();
	}

	// Check that makeNewAddress() wrote to its outputs.
	is_zero = 1;
	for (i = 0; i < 20; i++)
	{
		if (address2[i] != 0)
		{
			is_zero = 0;
			break;
		}
	}
	if (is_zero)
	{
		printf("makeNewAddress() doesn't write the address\n");
		reportFailure();
	}
	else
	{
		reportSuccess();
	}
	if (bigIsZero(public_key.x))
	{
		printf("makeNewAddress() doesn't write the public key\n");
		reportFailure();
	}
	else
	{
		reportSuccess();
	}

	// Make some new addresses, up to a limit.
	// Also check that addresses are unique.
	newWallet(name);
	abort = 0;
	address_buffer = malloc(MAX_TESTING_ADDRESSES * 20);
	for (i = 0; i < MAX_TESTING_ADDRESSES; i++)
	{
		if (makeNewAddress(&(address_buffer[i * 20]), &public_key) == BAD_ADDRESS_HANDLE)
		{
			printf("Couldn't create new address in new wallet\n");
			abort = 1;
			break;
		}
		for (j = 0; j < i; j++)
		{
			if (!memcmp(&(address_buffer[i * 20]), &(address_buffer[j * 20]), 20))
			{
				printf("Wallet addresses aren't unique\n");
				abort = 1;
				break;
			}
		}
		if (abort)
		{
			break;
		}
	}
	free(address_buffer);
	if (!abort)
	{
		reportSuccess();
	}
	else
	{
		reportFailure();
	}

	// The wallet should be full now.
	// Check that making a new address now causes an appropriate error.
	if (makeNewAddress(temp, &public_key) == BAD_ADDRESS_HANDLE)
	{
		if (walletGetLastError() == WALLET_FULL)
		{
			reportSuccess();
		}
		else
		{
			printf("Creating a new address on a full wallet gives incorrect error\n");
			reportFailure();
		}
	}
	else
	{
		printf("Creating a new address on a full wallet succeeds (it's not supposed to)\n");
		reportFailure();
	}

	// Check that getNumAddresses() fails when the wallet is empty.
	newWallet(name);
	if (getNumAddresses() == 0)
	{
		if (walletGetLastError() == WALLET_EMPTY)
		{
			reportSuccess();
		}
		else
		{
			printf("getNumAddresses() doesn't recognise wallet is empty\n");
			reportFailure();
		}
	}
	else
	{
		printf("getNumAddresses() succeeds when used on empty wallet\n");
		reportFailure();
	}

	// Create a bunch of addresses in the (now empty) wallet and check that
	// getNumAddresses() returns the right number.
	address_buffer = malloc(MAX_TESTING_ADDRESSES * 20);
	public_key_buffer = malloc(MAX_TESTING_ADDRESSES * sizeof(PointAffine));
	handles_buffer = malloc(MAX_TESTING_ADDRESSES * sizeof(AddressHandle));
	abort = 0;
	for (i = 0; i < MAX_TESTING_ADDRESSES; i++)
	{
		ah = makeNewAddress(&(address_buffer[i * 20]), &(public_key_buffer[i]));
		handles_buffer[i] = ah;
		if (ah == BAD_ADDRESS_HANDLE)
		{
			printf("Couldn't create new address in new wallet\n");
			abort = 1;
			reportFailure();
			break;
		}
	}
	if (!abort)
	{
		reportSuccess();
	}
	if (getNumAddresses() == MAX_TESTING_ADDRESSES)
	{
		reportSuccess();
	}
	else
	{
		printf("getNumAddresses() returns wrong number of addresses\n");
		reportFailure();
	}

	// The wallet should contain unique addresses.
	abort_duplicate = 0;
	for (i = 0; i < MAX_TESTING_ADDRESSES; i++)
	{
		for (j = 0; j < i; j++)
		{
			if (!memcmp(&(address_buffer[i * 20]), &(address_buffer[j * 20]), 20))
			{
				printf("Wallet has duplicate addresses\n");
				abort_duplicate = 1;
				reportFailure();
				break;
			}
		}
	}
	if (!abort_duplicate)
	{
		reportSuccess();
	}

	// The wallet should contain unique public keys.
	abort_duplicate = 0;
	for (i = 0; i < MAX_TESTING_ADDRESSES; i++)
	{
		for (j = 0; j < i; j++)
		{
			if (bigCompare(public_key_buffer[i].x, public_key_buffer[j].x) == BIGCMP_EQUAL)
			{
				printf("Wallet has duplicate public keys\n");
				abort_duplicate = 1;
				reportFailure();
				break;
			}
		}
	}
	if (!abort_duplicate)
	{
		reportSuccess();
	}

	// The address handles should start at 1 and be sequential.
	abort = 0;
	for (i = 0; i < MAX_TESTING_ADDRESSES; i++)
	{
		if (handles_buffer[i] != (AddressHandle)(i + 1))
		{
			printf("Address handle %d should be %d, but got %d\n", i, i + 1, (int)handles_buffer[i]);
			abort = 1;
			reportFailure();
			break;
		}
	}
	if (!abort)
	{
		reportSuccess();
	}

	// While there's a bunch of addresses in the wallet, check that
	// getAddressAndPublicKey() obtains the same address and public key as
	// makeNewAddress().
	abort_error = 0;
	abort = 0;
	for (i = 0; i < MAX_TESTING_ADDRESSES; i++)
	{
		ah = handles_buffer[i];
		if (getAddressAndPublicKey(address1, &public_key, ah) != WALLET_NO_ERROR)
		{
			printf("Couldn't obtain address in wallet\n");
			abort_error = 1;
			reportFailure();
			break;
		}
		if ((memcmp(address1, &(address_buffer[i * 20]), 20))
			|| (bigCompare(public_key.x, public_key_buffer[i].x) != BIGCMP_EQUAL)
			|| (bigCompare(public_key.y, public_key_buffer[i].y) != BIGCMP_EQUAL))
		{
			printf("getAddressAndPublicKey() returned mismatching address or public key, ah = %d\n", i);
			abort = 1;
			reportFailure();
			break;
		}
	}
	if (!abort)
	{
		reportSuccess();
	}
	if (!abort_error)
	{
		reportSuccess();
	}

	// Test getAddressAndPublicKey() and getPrivateKey() functions using
	// invalid and then valid address handles.
	if (getAddressAndPublicKey(temp, &public_key, 0) == WALLET_INVALID_HANDLE)
	{
		reportSuccess();
	}
	else
	{
		printf("getAddressAndPublicKey() doesn't recognise 0 as invalid address handle\n");
		reportFailure();
	}
	if (getPrivateKey(temp, 0) == WALLET_INVALID_HANDLE)
	{
		reportSuccess();
	}
	else
	{
		printf("getPrivateKey() doesn't recognise 0 as invalid address handle\n");
		reportFailure();
	}
	if (getAddressAndPublicKey(temp, &public_key, BAD_ADDRESS_HANDLE) == WALLET_INVALID_HANDLE)
	{
		reportSuccess();
	}
	else
	{
		printf("getAddressAndPublicKey() doesn't recognise BAD_ADDRESS_HANDLE as invalid address handle\n");
		reportFailure();
	}
	if (getPrivateKey(temp, BAD_ADDRESS_HANDLE) == WALLET_INVALID_HANDLE)
	{
		reportSuccess();
	}
	else
	{
		printf("getPrivateKey() doesn't recognise BAD_ADDRESS_HANDLE as invalid address handle\n");
		reportFailure();
	}
	if (getAddressAndPublicKey(temp, &public_key, handles_buffer[0]) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("getAddressAndPublicKey() doesn't recognise valid address handle\n");
		reportFailure();
	}
	if (getPrivateKey(temp, handles_buffer[0]) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("getPrivateKey() doesn't recognise valid address handle\n");
		reportFailure();
	}

	free(address_buffer);
	free(public_key_buffer);
	free(handles_buffer);

	// Check that changeEncryptionKey() works.
	memset(new_encryption_key, 0, WALLET_ENCRYPTION_KEY_LENGTH);
	new_encryption_key[0] = 1;
	if (changeEncryptionKey(new_encryption_key) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("Couldn't change encryption key\n");
		reportFailure();
	}

	// Check that the version field is "encrypted wallet".
	if (getWalletInfo(version, temp) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() failed after changeEncryptionKey() was called\n");
		reportFailure();
	}
	if (readU32LittleEndian(version) == VERSION_IS_ENCRYPTED)
	{
		reportSuccess();
	}
	else
	{
		printf("changeEncryptionKey() does not set version to encrypted wallet\n");
		reportFailure();
	}

	// Check name matches what was given in newWallet().
	if (!memcmp(temp, name, NAME_LENGTH))
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() doesn't return correct name when wallet is loaded\n");
		reportFailure();
	}

	// Check that getWalletInfo() still works after unloading wallet.
	uninitWallet();
	if (getWalletInfo(version, temp) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() failed after uninitWallet() was called\n");
		reportFailure();
	}
	if (readU32LittleEndian(version) == VERSION_IS_ENCRYPTED)
	{
		reportSuccess();
	}
	else
	{
		printf("uninitWallet() caused wallet version to change\n");
		reportFailure();
	}

	// Check name matches what was given in newWallet().
	if (!memcmp(temp, name, NAME_LENGTH))
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() doesn't return correct name when wallet is not loaded\n");
		reportFailure();
	}

	// Change wallet's name and check that getWalletInfo() reflects the
	// name change.
	initWallet();
	memcpy(name, "HHHHH HHHHHHHHHHHHHHHHH HHHHHHHHHHHHHH  ", NAME_LENGTH);
	if (changeWalletName(name) == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("changeWalletName() couldn't change name\n");
		reportFailure();
	}
	getWalletInfo(version, temp);
	if (!memcmp(temp, name, NAME_LENGTH))
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() doesn't reflect name change\n");
		reportFailure();
	}

	// Check that name change is preserved when unloading and loading a
	// wallet.
	uninitWallet();
	getWalletInfo(version, temp);
	if (!memcmp(temp, name, NAME_LENGTH))
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() doesn't reflect name change after unloading wallet\n");
		reportFailure();
	}

	// Check that initWallet() succeeds (changing the name changes the
	// checksum, so this tests whether the checksum was updated).
	if (initWallet() == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("initWallet() failed after name change\n");
		reportFailure();
	}
	getWalletInfo(version, temp);
	if (!memcmp(temp, name, NAME_LENGTH))
	{
		reportSuccess();
	}
	else
	{
		printf("getWalletInfo() doesn't reflect name change after reloading wallet\n");
		reportFailure();
	}

	// Check that loading the wallet with the old key fails.
	uninitWallet();
	setEncryptionKey(encryption_key);
	if (initWallet() == WALLET_NOT_THERE)
	{
		reportSuccess();
	}
	else
	{
		printf("Loading wallet with old encryption key succeeds\n");
		reportFailure();
	}

	// Check that loading the wallet with the new key succeeds.
	uninitWallet();
	setEncryptionKey(new_encryption_key);
	if (initWallet() == WALLET_NO_ERROR)
	{
		reportSuccess();
	}
	else
	{
		printf("Loading wallet with new encryption key fails\n");
		reportFailure();
	}

	// Test the getAddressAndPublicKey() and getPrivateKey() functions on an
	// empty wallet.
	newWallet(name);
	if (getAddressAndPublicKey(temp, &public_key, 0) == WALLET_EMPTY)
	{
		reportSuccess();
	}
	else
	{
		printf("getAddressAndPublicKey() doesn't deal with empty wallets correctly\n");
		reportFailure();
	}
	if (getPrivateKey(temp, 0) == WALLET_EMPTY)
	{
		reportSuccess();
	}
	else
	{
		printf("getPrivateKey() doesn't deal with empty wallets correctly\n");
		reportFailure();
	}

	fclose(wallet_test_file);

	finishTests();
	exit(0);
}