|
|
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 |
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 |
|
mirek
Messages: 13980 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 #33444 is a reply to message #33441] |
Sun, 07 August 2011 22:47 |
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 #33447 is a reply to message #33445] |
Mon, 08 August 2011 10:41 |
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 #33452 is a reply to message #33445] |
Tue, 09 August 2011 00:42 |
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 #33475 is a reply to message #33461] |
Thu, 11 August 2011 13:25 |
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
|
|
|
Goto Forum:
Current Time: Sun May 19 17:41:16 CEST 2024
Total time taken to generate the page: 0.00966 seconds
|
|
|