Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
Bazaar
Status & Roadmap
FAQ
Authors & License
Forums
Funding Ultimate++
Search on this site
Search in forums












SourceForge.net Logo
Home » U++ Library support » U++ Core » BUG? or Not BUG? LoadFile(filename) and then getting wrong data
BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33441] Sat, 06 August 2011 10:58 Go to next message
silverx is currently offline  silverx
Messages: 62
Registered: March 2011
Member
I am try to write a hex viewer, and I am using the following to get the data in from the file.

String mfileinfo = LoadFile(fs);

Then I am using

thebyte = mfileinfo[i];

Where i just counts through 1 byte at a time the data on the file.

I have tried with thebyte being defined as int unsigned, int, and char, and when it encounters a hex byte of C3 in the input file it gives the value as -61, also when it comes to a C8 it gives a -56 as the value for thebyte.

When C3 should return 195, and the C8 should return 200.

Why am I getting the what I think is the wrong value for those bytes? How do I get it to return the correct value?

Is this a BUG, problem with LoadFile? Should I use some other way to load the data into the program?

Thanks

David
Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33442 is a reply to message #33441] Sun, 07 August 2011 12:59 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12519
Registered: November 2005
Ultimate Member
silverx wrote on Sat, 06 August 2011 04:58

I am try to write a hex viewer, and I am using the following to get the data in from the file.

String mfileinfo = LoadFile(fs);

Then I am using

thebyte = mfileinfo[i];

Where i just counts through 1 byte at a time the data on the file.

I have tried with thebyte being defined as int unsigned, int, and char, and when it encounters a hex byte of C3 in the input file it gives the value as -61, also when it comes to a C8 it gives a -56 as the value for thebyte.

When C3 should return 195, and the C8 should return 200.

Why am I getting the what I think is the wrong value for those bytes? How do I get it to return the correct value?

Is this a BUG, problem with LoadFile? Should I use some other way to load the data into the program?

Thanks

David


Well, I know pretty sure LoadFile works. Means it is something else, but hard to say on so little info.

Anyway, (char)-61 is 0xc3, so the most likely reason is that you put data into 'char'....

Mirek
Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33443 is a reply to message #33442] Sun, 07 August 2011 16:49 Go to previous messageGo to next message
dolik.rce is currently offline  dolik.rce
Messages: 1778
Registered: August 2008
Location: Czech Republic
Senior Contributor

Hi David,
How do you check the values? It is quite possible that it gets converted to a signed type while you log them Wink I remmember I hit similar problem a while ago and spent a lot of time debugging correct code Smile

Best regards,
Honza
Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33444 is a reply to message #33441] Sun, 07 August 2011 22:47 Go to previous messageGo to next message
Sender Ghost is currently offline  Sender Ghost
Messages: 301
Registered: November 2008
Senior Member
Hello, David.

silverx wrote on Sat, 06 August 2011 10:58


Should I use some other way to load the data into the program?



You can use FileStream directly to read file or just FileIn:
#include <Core/Core.h>

using namespace Upp;

inline String PrintUsage() {
	StringBuffer sb;
	sb << "Prints hex view of selected file\n\n\
Syntax:\n"
<< GetExeTitle() << " [file]\n\n\
Options:\n\
file\t\t Path to selected file\n";
	return sb;
}

CONSOLE_APP_MAIN
{
	const Vector<String>& cl = CommandLine();

	if (cl.GetCount() == 0)
	{
		SetExitCode(0);
		Cout() << PrintUsage();
		return;
	}

	String filePath(NormalizePath(cl[0]));

	if (!FileExists(filePath))
	{
		SetExitCode(1);
		Cerr() << Format("File \"%s\" doesn't exists\n", filePath);
		return;
	}

	FileIn fs;

	if (!fs.Open(filePath))
	{
		SetExitCode(1);
		Cerr() << Format("Can't read \"%s\" file\n", filePath);
		return;
	}

	const int wrapCount = 16;
	int lineCount = 0,
		columnCount = 0;

	StringBuffer text;

	while (!fs.IsEof())
	{
		if (columnCount == 0)
			Cout() << Format("%7s:", Format64Hex(lineCount++ * wrapCount));

		const int data = fs.Get();
		text.Cat(!iscntrl(data) ? char(data) : '.');
		const String hex = Format64Hex(data);
		Cout() << Format(" %2s", hex);

		if (++columnCount == wrapCount)
		{
			columnCount = 0;
			Cout() << " | " << ~text << '\n';
			text.Clear();
		}
	}

	if (text.GetCount() > 0)
	{
		const String fmt = String().Cat() << '%' << 3 * (wrapCount - columnCount + 1) << 's';
		Cout() << Format(fmt, " | ") << ~text << '\n';
	}
}


With OutStream implementation, while copying (for files larger than 128 bytes):
#include <Core/Core.h>

using namespace Upp;

inline String PrintUsage() {
	StringBuffer sb;
	sb << "Prints hex view of selected file\n\n\
Syntax:\n"
<< GetExeTitle() << " [file]\n\n\
Options:\n\
file\t\t Path to selected file\n";
	return sb;
}

class HexStream : public OutStream {
private:
	const int wrapCount;
	int columnCount,
		lineCount;
	Stream *stream;
public:
	HexStream(Stream *toStream) : stream(toStream), wrapCount(16), columnCount(0), lineCount(0) { }

	virtual void Out(const void *data, dword size)
	{
		StringBuffer text;

		const byte *s = (const byte *)data;

		for (dword i = 0; i < size; ++i)
		{
			if (columnCount == 0)
				*stream << Format("%7s:", Format64Hex(lineCount++ * wrapCount));

			const byte& value = s[i];
			text.Cat(!iscntrl(value) ? char(value) : '.');
			const String hex = Format64Hex(value);
			*stream << Format(" %2s", hex);

			if (++columnCount == wrapCount)
			{
				columnCount = 0;
				*stream << " | " << ~text << '\n';
				text.Clear();
			}
		}

		if (text.GetCount() > 0)
		{
			const String fmt = String().Cat() << '%' << 3 * (wrapCount - columnCount + 1) << 's';
			*stream << Format(fmt, " | ") << ~text << '\n';
		}
	}
};

CONSOLE_APP_MAIN
{
	const Vector<String>& cl = CommandLine();

	if (cl.GetCount() == 0)
	{
		SetExitCode(0);
		Cout() << PrintUsage();
		return;
	}

	String filePath(NormalizePath(cl[0]));

	if (!FileExists(filePath))
	{
		SetExitCode(1);
		Cerr() << Format("File \"%s\" doesn't exists\n", filePath);
		return;
	}

	FileIn fs;

	if (!fs.Open(filePath))
	{
		SetExitCode(1);
		Cerr() << Format("Can't read \"%s\" file\n", filePath);
		return;
	}

	HexStream stream(&Cout());
	/*const int64 count =*/
	CopyStream(stream, fs);
}


Edit: Added example with OutStream.

[Updated on: Mon, 08 August 2011 21:27]

Report message to a moderator

Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33445 is a reply to message #33443] Mon, 08 August 2011 09:48 Go to previous messageGo to next message
silverx is currently offline  silverx
Messages: 62
Registered: March 2011
Member
Ok, I have attached a file. It has the smallsample2.dat which is the input file. It is in byte 12 and a couple of bytes after that it shows in the promptok as being a negative number. As you can see I defined thebyte as int unsigned, which means it shouldn't have any sign to it.

Then I have 2 programs. The first that is bad which is ReadFullFill, and it gives bad results.

Then I have a program ReadFileByte, which uses the reading it one byte at a time from the input file. Which when I try and process the large file it takes for ever, and gives me program not responding. Another issue I need to find out what to do about it.

Anyway the ReadFileByte, it gives the correct result.

I am using the int value in my program as an index into an array to get me data. And when it comes back as a negative number it was causing data exceptions error as the index put it outside of the array.

I am using the same define in both programs. And as I said I tried to use char in the bad program and got the same result.

David
Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33446 is a reply to message #33445] Mon, 08 August 2011 09:50 Go to previous messageGo to next message
silverx is currently offline  silverx
Messages: 62
Registered: March 2011
Member
forgot the attachment.
Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33447 is a reply to message #33445] Mon, 08 August 2011 10:41 Go to previous messageGo to next message
Sender Ghost is currently offline  Sender Ghost
Messages: 301
Registered: November 2008
Senior Member
silverx wrote on Mon, 08 August 2011 09:48


Ok, I have attached a file. It has the smallsample2.dat which is the input file. It is in byte 12 and a couple of bytes after that it shows in the promptok as being a negative number.



I have following output for "smallsample2.dat" file, using first variant of example program:
      0: 50 4b  3  4 14  0  0  0  8  0 34 5c c3 3e 26 c8 | PK........4\>&
     10: 51 e7 d5                                        | Q


Here, we can see, that control characters used (chars with '.') on the right side of the output. They don't have printable characters (but you could specify them, which depends from implementation (e.g. by special images, character sequences, etc.)). However, as Mirek said, you just need correct conversion to byte to see integer values from char, then PromptOK will show it.

Edit: Corrected sentence about PromptOK.

[Updated on: Mon, 08 August 2011 19:51]

Report message to a moderator

Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33448 is a reply to message #33447] Mon, 08 August 2011 13:24 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12519
Registered: November 2005
Ultimate Member
	for (i=0; i<fl; i++)
	{
		
		
	    thebyte = mfileinfo[i];	    


The problem is in above line. The issue is that String is a collection of 'char' elements, which are signed entities. Therefore, it returns negative value for 0xc3.

There is little that can be done about it, as long as we want to be compatible with

char h[1] = { 0xc3 }

h[0] in any expression would yield a negative value as well.

So this problem is deeply buried in C++ resolution to use signed value for char.

However, fix is trivial:

	for (i=0; i<fl; i++)
	{
	    thebyte = (byte)mfileinfo[i];	    


Mirek
Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33452 is a reply to message #33445] Tue, 09 August 2011 00:42 Go to previous messageGo to next message
Sender Ghost is currently offline  Sender Ghost
Messages: 301
Registered: November 2008
Senior Member
silverx wrote on Mon, 08 August 2011 09:48


Then I have a program ReadFileByte, which uses the reading it one byte at a time from the input file. Which when I try and process the large file it takes for ever, and gives me program not responding. Another issue I need to find out what to do about it.


Another interesting way is to use FileMapping to get blocks of data to process it:
#include <Core/Core.h>

using namespace Upp;

inline String PrintUsage() {
	StringBuffer sb;
	sb << "Prints hex view of selected file\n\n\
Syntax:\n"
<< GetExeTitle() << " [file]\n\n\
Options:\n\
file\t\t Path to selected file\n";
	return sb;
}

CONSOLE_APP_MAIN
{
	const Vector<String>& cl = CommandLine();

	if (cl.GetCount() == 0)
	{
		SetExitCode(0);
		Cout() << PrintUsage();
		return;
	}

	String filePath(NormalizePath(cl[0]));

	if (!FileExists(filePath))
	{
		SetExitCode(1);
		Cerr() << Format("File \"%s\" doesn't exists\n", filePath);
		return;
	}

	FileMapping fm;

	if (!fm.Open(filePath))
	{
		SetExitCode(1);
		Cerr() << Format("Can't read \"%s\" file\n", filePath);
		return;
	}

	const int wrapCount = 16,
		blockSize = wrapCount * 4096;

	int64 count = fm.GetFileSize(),
		offset = 0;

	while (count > 0)
	{
		const int lenght = min<int64>(count, blockSize);
		const String& data = fm.GetData(offset, lenght);
		count -= lenght; offset += lenght;

		for (int i = 0; i < data.GetCount(); ++i)
		{
			const String& hex = Format64Hex(byte(data[i]));
			Cout() << Format(" %2s", hex);

			if ((i + 1) % wrapCount == 0)
				Cout() << '\n';
		}
	}
}

mirek wrote on Mon, 08 August 2011 13:24


However, fix is trivial


Thanks for fix, Mirek.
Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33458 is a reply to message #33448] Tue, 09 August 2011 12:15 Go to previous messageGo to next message
silverx is currently offline  silverx
Messages: 62
Registered: March 2011
Member
Thank you for the fix. I tried it and it works.

Now I just have to figure out how to do a progress when reading in a large file, as the program window gets a message of (not responding) on it. When in fact it is still working.

david
Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33461 is a reply to message #33458] Tue, 09 August 2011 13:07 Go to previous messageGo to next message
mirek is currently offline  mirek
Messages: 12519
Registered: November 2005
Ultimate Member
silverx wrote on Tue, 09 August 2011 06:15

Thank you for the fix. I tried it and it works.

Now I just have to figure out how to do a progress when reading in a large file, as the program window gets a message of (not responding) on it. When in fact it is still working.

david


Add Progress...

Mirek

[Updated on: Tue, 09 August 2011 13:07]

Report message to a moderator

Re: BUG? or Not BUG? LoadFile(filename) and then getting wrong data [message #33475 is a reply to message #33461] Thu, 11 August 2011 13:25 Go to previous message
silverx is currently offline  silverx
Messages: 62
Registered: March 2011
Member
Add the progress widget to it.

I noticed no working example of the widget progress.

I did manage to get it working. Here is an example of that along with the read that has the fix in it you suggested.

While it only reads data, and not puts out anything, it does a progress of the read of the file. You need to have a 20K or larger file probably to see it work.

Feel free to use it as an example, bazzar, or reference, of the widget progress with a cancel button for people to see.

David Corning
Previous Topic: Polymorphic Array doubt
Next Topic: Need help about the codepage!
Goto Forum:
  


Current Time: Thu Jun 04 08:11:20 CEST 2020

Total time taken to generate the page: 0.01731 seconds