Recent

Author Topic: need help with show a file like this  (Read 40863 times)

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #30 on: September 27, 2015, 07:49:49 pm »
got something wrong with the date.
Now I have to show the Field according to its number. and the FieldData.
the crappy thing is: I have to update the date with the current system's YYYY/MM/DD but SysUtils's got GetDate. I could use that?
No. I saw somewhere in your pdf that the data field is comprised of 7 bits for the year, 4 bits for the month and 5 bits for the day. So you need to do some bit-shifting to get the correct values for year, month and day.

And I think the year is an offset of 2000. You can see it at the end of that pdf but I can't read that language (Spanish?).

yes I was told to use shift.

"Date: this type of data represents a date (duh) stored in 2 bytes
1st BYTE:
7 bits YEAR; 1 bit MONTH
2nd BYTE:
3 bits MONTH; 5 bits DAY

2p5=2*2*2*2*2
Year: 2p7-1=127 Month: 2p4-1=15 Day: 2p5-1=32

7 bits from left are YEAR, next 4 bits are MONTH, last 5 bits are DAY.

being A the value of year in a date; it should be taken like this:
if A<100; its 2000+A
if A>=100; its 1999-A+100

example:
if A=125 then: 1999-A+100=1974
if A=4 then: 2000-A=2004
"

rvk

  • Hero Member
  • *****
  • Posts: 6675
Re: need help with create a file like this
« Reply #31 on: September 27, 2015, 07:51:50 pm »
I just added some info on my previous answer.

I'll help you along some...  :D Very rudimentary code:
Code: [Select]
  Header.Date := BEtoN(Header.Date);
  Writeln('Year offset to 2000: ', (Header.Date and %1111111000000000) shr (5+4));
  Writeln('Month: ', (Header.Date and %0000000111100000) shr 5);
  Writeln('Day: ', (Header.Date and %0000000000011111));
You see I do a bitwise AND to exclude the other bits in the field and after that I shift the bits to the right until the important bits are all at the end.

For writing you should do a shift of the bits to the left and an OR.

If you don't understand bitwise operations you might want to read up on them:
https://en.wikipedia.org/wiki/Bitwise_operation
(with that you should be able to do anything with the date)

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #32 on: September 27, 2015, 08:57:16 pm »
I'm getting errors in
myRead(Fields.Fieldnr, 2);
myRead(Fields.Fieldname, 1);
myRead(Fields.FieldData, 1);

and by that for nrs := 0 to Fields.Fieldnr - 1do  isnt working.

Code: [Select]
program Crear;
uses SysUtils;
type
  THeader = record
    Serial: Word;   //2 bytes
    Filename: String[255];  //1 byte
    Date: Word;  //2 bytes
    Fieldnrs: Word;  //2 bytes
  end;
  TFields = record
    Fieldnr: Word;   //2 bytes
    Fieldname: String[255];   //1 byte
    FieldData: String[255]; //1 Byte
  end;
var
  BinaryStream: File;
  Header: THeader;
  Fields: array [0..20] of TFields;
  nrs: Integer;  //2 bytes

procedure myRead(var Buffer; Size: Integer);
  begin
    BlockRead(BinaryStream, Buffer, Size);
  end;

begin
  assign(BinaryStream, 'C:\Dev-Pas\EXAMEN2.dat');
  reset(BinaryStream, 1);
  myRead(Header.Serial, 2);
  myRead(Header.Filename[0], 1);
  myRead(Header.Filename[1], ord(Header.Filename[0]));
  myRead(Header.Date, 2);
  myRead(Header.Fieldnrs, 2);

  Header.Serial := Swap(Header.Serial);
  Header.Fieldnrs := Swap(Header.Fieldnrs);

  for nrs := 0 to Header.Fieldnrs - 1 do
  begin
       myRead (Fields[nrs].Fieldnr, 2);
       Fields[nrs].Fieldnr := Swap (Fields [nrs].Fieldnr);
       myRead (Fields[nrs].Fieldname[0],1);
       myRead (Fields[nrs].Fieldname[1], ord(Fields[nrs].Fieldname[0]));
  end;

       Writeln ('Nro. de Serie: ', Header.Serial);
       Writeln ('Full Filename: ', Header.Filename);
       Writeln ('Fecha Modificacion: ', Header.Date);
       Writeln ('Cantidad de Campos Customizados: ', Header.Fieldnrs);

       for nrs := 0 to Header.Fieldnrs - 1 do
       begin
            Writeln ('Campo [codigo: ',Fields[nrs].Fieldnr,', ','descripcion: ',Fields[nrs].Fieldname ,']' );
       end;
       Writeln ('Cantidad de Registros: ', nrs);
       Writeln ('------------------------');

       myRead(Fields.Fieldnr, 2);
       myRead(Fields.Fieldname, 1);
       myRead(Fields.FieldData, 1);


       for nrs := 0 to Fields.Fieldnr - 1 do
       begin
            Writeln (Fields[nrs].Fieldname,': ',Fields[nrs].FieldData);
            inc(nrs);
       end;

       Writeln ('----[FIN CONTENIDO DEL ARCHIVO]-----------------');


Close(BinaryStream);
ReadLn;
end.
« Last Edit: September 27, 2015, 08:58:58 pm by GMP_47 »

rvk

  • Hero Member
  • *****
  • Posts: 6675
Re: need help with create a file like this
« Reply #33 on: September 27, 2015, 09:11:42 pm »
I'm getting errors in
myRead(Fields.Fieldnr, 2);
myRead(Fields.Fieldname, 1);
myRead(Fields.FieldData, 1);

and by that for nrs := 0 to Fields.Fieldnr - 1do  isnt working.
Fields is an array which contains the fieldnames you've just read.
You can't use that same variable to read the records.

You need to create a new variable to a record-type.

For instance:
Code: [Select]
type
  TRecordField = record
    Fieldnr: Word;
    FieldText: String[255];
  end;

var
  Rec: array[0..10] of TRecord;
After that you can read the real data of the records in variable Rec.

(And don't forget to first read the variable NumberOfRecords which is also in the file and you forgot to read first)

After that, if I remember correctly, there was a field containing the number of used fields in the record.
(Not all fields have to be in a record)

So (pseudocode):
Code: [Select]
Read NumberOfRecords
for/next 0 to NumberOfRecords - 1
begin
  Empty all fields (clear record Rec)
  Read NumberOfFieldsInRecord
  for/next 0 to NumberOfFieldsInRecord - 1
  begin
    Read Fieldnr
    Read stringlength
    Read Rec[Fieldnr].FieldText (stringlength characters)
  end;

  Printout record Rec

end;

And again... you can't read Fields.Fieldname like that. First read the length of the string and then the characters themselves.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #34 on: September 27, 2015, 09:49:16 pm »
Code: [Select]
type
  THeader = record
    Serial: Word;   //2 bytes
    Filename: String[255];  //1 byte
    Date: Word;  //2 bytes
    Fieldnrs: Word;  //2 bytes
    NrsRecords: Integer;
first, it's giving me Number of Records 0.
nrsRecords is supposed to be in the file, right? I need that so I can do the For

rvk

  • Hero Member
  • *****
  • Posts: 6675
Re: need help with create a file like this
« Reply #35 on: September 27, 2015, 09:51:17 pm »
first, it's giving me Number of Records 0.
nrsRecords is supposed to be in the file, right? I need that so I can do the For
Yes, it is.
How are you reading it now?

(and don't forget to do the Header.NrsRecords := BEtoN(Header.NrsRecords); after reading it)

Edit: O wow, I see FPC 1.0.6 also doesn't have BEtoN. So you need to keep using swap() for that. I really can't understand why they would encourage such an ancient FPC-version.
« Last Edit: September 27, 2015, 09:58:19 pm by rvk »

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #36 on: September 27, 2015, 09:57:36 pm »
first, it's giving me Number of Records 0.
nrsRecords is supposed to be in the file, right? I need that so I can do the For
Yes, it is.
How are you reading it now?

(and don't forget to do the Header.NrsRecords := BEtoN(Header.NrsRecords); after reading it)

Code: [Select]
assign(BinaryStream, 'C:\Dev-Pas\EXAMEN2.dat');
  reset(BinaryStream, 1);
  myRead(Header.Serial, 2);
  myRead(Header.Filename[0], 1);
  myRead(Header.Filename[1], ord(Header.Filename[0]));
  myRead(Header.Date, 2);
  myRead(Header.Fieldnrs, 2);
  myRead(Header.NrsRecords, 2);

  Header.NrsRecords := BEtoN(Header.NrsRecords);
  Header.Serial := Swap(Header.Serial);
  Header.Fieldnrs := Swap(Header.Fieldnrs);
BETON gives error. do you know other process?

rvk

  • Hero Member
  • *****
  • Posts: 6675
Re: need help with create a file like this
« Reply #37 on: September 27, 2015, 09:58:40 pm »
O wow, I see FPC 1.0.6 also doesn't have BEtoN. So you need to keep using swap() for that. I really can't understand why they would encourage such an ancient FPC-version.

rvk

  • Hero Member
  • *****
  • Posts: 6675
Re: need help with create a file like this
« Reply #38 on: September 27, 2015, 10:00:11 pm »
B.T.W. the myRead(Header.NrsRecords, 2); should be AFTER reading the fieldnames. You now have it BEFORE the fieldnames.

Look at your assignment and the order of the fields they gave you.

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #39 on: September 27, 2015, 10:10:28 pm »
B.T.W. the myRead(Header.NrsRecords, 2); should be AFTER reading the fieldnames. You now have it BEFORE the fieldnames.

Look at your assignment and the order of the fields they gave you.

NrsRecords is the number of contacts listed in total so it goes in the last line of the example.

----[CONTENIDO DEL ARCHIVO]--------------------
Nro. de Serie: 43112
Full Filename: C:/DEMO.dat
Fecha Modificacion: 2014/9/20
Cantidad de Campos Customizados: 4
Campo [codigo: 1, descripcion: Nombre]
Campo [codigo: 2, descripcion: Telefono]
Campo [codigo: 3, descripcion: Direccion]
Campo [codigo: 4, descripcion: EMail]
Cantidad de Registros: 5  total reg counter
also, why that long number?
Code: [Select]
program Crear;
uses SysUtils;
type
  THeader = record
    Serial: Word;   //2 bytes
    Filename: String[255];  //1 byte
    Date: Word;  //2 bytes
    Fieldnrs: Word;  //2 bytes
    NrsRecords: Integer;  //2 bytes
  end;
  TFields = record
    Fieldnr: Word;   //2 bytes
    Fieldname: String[255];   //1 byte
    FieldData: String[255]; //1 Byte
  end;
  TRecordField = record
    Fieldnr: Word;
    FieldText: String[255];
  end;
var
  BinaryStream: File;
  Header: THeader;
  Fields: array [0..20] of TFields;
  Rec: array[0..20] of TRecordField;
  nrs: Integer;  //2 bytes

procedure myRead(var Buffer; Size: Integer);
  begin
    BlockRead(BinaryStream, Buffer, Size);
  end;

begin
  assign(BinaryStream, 'C:\Dev-Pas\EXAMEN2.dat');
  reset(BinaryStream, 1);
  myRead(Header.Serial, 2);
  myRead(Header.Filename[0], 1);
  myRead(Header.Filename[1], ord(Header.Filename[0]));
  myRead(Header.Date, 2);
  myRead(Header.Fieldnrs, 2);

  Header.Serial := Swap(Header.Serial);
  Header.Fieldnrs := Swap(Header.Fieldnrs);

  for nrs := 0 to Header.Fieldnrs - 1 do
  begin
       myRead (Fields[nrs].Fieldnr, 2);
       Fields[nrs].Fieldnr := Swap (Fields [nrs].Fieldnr);
       myRead (Fields[nrs].Fieldname[0],1);
       myRead (Fields[nrs].Fieldname[1], ord(Fields[nrs].Fieldname[0]));
  end;
       myRead(Header.NrsRecords, 2);
       Header.NrsRecords := Swap(Header.NrsRecords);

       Writeln ('Nro. de Serie: ', Header.Serial);
       Writeln ('Full Filename: ', Header.Filename);
       Writeln ('Fecha Modificacion: ', Header.Date);
       Writeln ('Cantidad de Campos Customizados: ', Header.Fieldnrs);
       Writeln ('Cantidad de Registros: ', Header.NrsRecords);
       for nrs := 0 to Header.Fieldnrs - 1 do
       begin
            Writeln ('Campo [codigo: ',Fields[nrs].Fieldnr,', ','descripcion: ',Fields[nrs].Fieldname ,']' );
       end;
       Writeln ('Cantidad de Registros: ', Header.NrsRecords);
       Writeln ('------------------------');


       for nrs := 0 to Header.NrsRecords - 1 do
       begin

       end;

       Writeln ('----[FIN CONTENIDO DEL ARCHIVO]-----------------');
Close(BinaryStream);
ReadLn;
end.

rvk

  • Hero Member
  • *****
  • Posts: 6675
Re: need help with create a file like this
« Reply #40 on: September 27, 2015, 10:17:59 pm »
Why did you declare NrsRecords as Integer? An Integer is a signed 2 byte value (i.e. −32,768 to 32,767). I thought we already established you were dealing with WORDs. So make it a WORD and it should work fine.

rvk

  • Hero Member
  • *****
  • Posts: 6675
Re: need help with create a file like this
« Reply #41 on: September 27, 2015, 10:27:13 pm »
For me it says this:
Code: [Select]
Nro. de Serie: 14141
Full Filename: d:/documentos/testing/examen2.dat
Fecha Modificacion: 16905
Cantidad de Campos Customizados: 4
Cantidad de Registros: 5
Campo [codigo: 1, descripcion: Name]
Campo [codigo: 2, descripcion: Telephone]
Campo [codigo: 3, descripcion: Address]
Campo [codigo: 4, descripcion: EMail]
Cantidad de Registros: 5
------------------------
----[FIN CONTENIDO DEL ARCHIVO]-----------------

This is YOUR exact code with just the Integer changed to Word for NrsRecords.

(and there are 5 records in your file)


B.T.W you have two lines with "Cantidad de Registros".

molly

  • Hero Member
  • *****
  • Posts: 2330
Re: need help with create a file like this
« Reply #42 on: September 27, 2015, 10:34:16 pm »
O wow, I see FPC 1.0.6 also doesn't have BEtoN. So you need to keep using swap() for that. I really can't understand why they would encourage such an ancient FPC-version.
My memory fails me, but please be aware that you are probably very lucky to get away with using Swap, as there are no 4 byte values inside the structure. Better use SwapEndian (but no idea if that existed in that old FPC version).

Code: [Select]
program endianness;

{$DEFINE FILE_IS_BE} // or in case little endian -> {$DEFINE FILE_IS_LE}

{$IF DEFINED(FILE_IS_LE) and DEFINED(ENDIAN_BIG)}
{$DEFINE USE_SWAP}
{$INFO File is LE, system is BE -> We need to use swapping}
{$ENDIF}
{$IF DEFINED(FILE_IS_BE) and DEFINED(ENDIAN_LITTLE)}
{$DEFINE USE_SWAP}
{$INFO File is BE, system is LE -> We need to use swapping}
{$ENDIF}

Uses
  SysUtils;

Var
  TestValue  : LongWord;
  Answer1    : LongWord;
  Answer2    : LongWord;
  Answer3    : LongWord;
 
begin
  TestValue := $12345678;
  WriteLn('TestValue before : ', IntToHex(TestValue, 8));

  {$IFDEF USE_SWAP}
  WriteLn('We need to swap');
  Answer1 := Swap(TestValue);
  Answer2 := SwapEndian(TestValue);
  {$IFDEF FILE_IS_BE}
  Answer3 := BEtoN(TestValue);
  {$ENDIF}
  {$IFDEF FILE_IS_LE}
  Answer3 := LEtoN(TestValue);
  {$ENDIF}
  {$ELSE}
  WriteLn('We don''t need to swap');
  Answer1 := TestValue;
  Answer2 := TestValue;
  Answer3 := TestValue;
  {$ENDIF}

  WriteLn('      Swap() Answer : ', IntToHex(Answer1, 8));
  WriteLn('SwapEndian() Answer : ', IntToHex(Answer2, 8));
  WriteLn('     XeToN() Answer : ', IntToHex(Answer3, 8));
end.

Produces:
Code: [Select]
TestValue before : 12345678
We need to swap
      Swap() Answer : 56781234
SwapEndian() Answer : 78563412
     XeToN() Answer : 78563412
« Last Edit: September 27, 2015, 10:37:19 pm by molly »

rvk

  • Hero Member
  • *****
  • Posts: 6675
Re: need help with create a file like this
« Reply #43 on: September 27, 2015, 10:37:41 pm »
My memory fails me, but please be aware that you are probably very lucky to get away with using Swap, as there are no 4 byte values inside the structure. Better use SwapEndian (but no idea if that existed in that old FPC version).
No, FPC 1.0.6 doesn't know SwapEndian.

But all the swap() procedure are overloaded and the one with swap(x:word) works correctly.

Also in the newer FPC the swap(x:word) just calls SwapEndian(X).

GMP_47

  • Jr. Member
  • **
  • Posts: 60
Re: need help with create a file like this
« Reply #44 on: September 27, 2015, 10:38:12 pm »
For me it says this:
Code: [Select]
Nro. de Serie: 14141
Full Filename: d:/documentos/testing/examen2.dat
Fecha Modificacion: 16905
Cantidad de Campos Customizados: 4
Cantidad de Registros: 5
Campo [codigo: 1, descripcion: Name]
Campo [codigo: 2, descripcion: Telephone]
Campo [codigo: 3, descripcion: Address]
Campo [codigo: 4, descripcion: EMail]
Cantidad de Registros: 5
------------------------
----[FIN CONTENIDO DEL ARCHIVO]-----------------

This is YOUR exact code with just the Integer changed to Word for NrsRecords.

(and there are 5 records in your file)


B.T.W you have two lines with "Cantidad de Registros".
yeah. realized that.
Code: [Select]
for nrs := 0 to Header.NrsRecords - 1 do
       begin
       case Fields.Fieldnr of
            1: Writeln ('Nombre: ',Fields.FieldText);
            2: Writeln ('Telefono: ',Fields.FieldText);
            3: Writeln ('Direccion: ',Fields.FieldText);
            4: Writeln ('EMail: ',Fields.FieldText);
       end;
I made this so that every time it checks Fields.Fieldnr (1,2,3 and/or 4) it writes its respective name and info.
but there's an error in it. is not taking "Fields.Fieldnr" correctly.

 

TinyPortal © 2005-2018