Solved

Help with String Sizes Problums.

Posted on 2004-03-21
9
601 Views
Last Modified: 2008-02-26
Hi experts I am designing a liveUpdate program creator. anyway the program is going quite well but am having some problums with string anyway I have a recored like the one below in a unit file

Type
    Header = record
    Version : ShortString;
    ProgName : ShortString;
    UpdateFile : ShortString;
    HomePage : ShortString;
    UpDateUrl : ShortString;
    VerFoundInfo : ShortString;
    VerInfo : ShortString;
    DownloadDoneInfo : ShortString;
End;

Ok the record above as you may already tell  am storeing information about the program's update

My problums is that VerFoundInfo will only allow me to add 255 char some times I may need more than this I have tryed to use WideString but when I try to read the info it does not work. or reports errors is there something I am doing wrong please help PS i am only starting to learn Delphi from moveing from VB so any help whoule be helpfull.

PS the recored aboeve I also write to a file I left the code below incase there may be something wrong there.


procedure WriteUpdate(lzFile : String);
Var
    f : File;
Begin
    AssignFile(F,lzFile);
    reWrite(F,1);
    BlockWrite(F,sUpdate,SizeOf(sUpdate));
    CloseFile(F);
End;

procedure ReadUpdate(lzFile : String);
Var
    f : File;
Begin
    AssignFile(F,lzFile);
    Reset(F,1);
    BlockRead(F,sUpdate,SizeOf(sUpdate));
    CloseFile(F);
End;


Thanks.

Var sUpdate : Header;

0
Comment
Question by:dreamvb
9 Comments
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Type

    THeader = class
    public
     Version : String;
     ProgName : String;
     UpdateFile : String;
     HomePage : String;
     UpDateUrl : String;
     VerInfo : String;
     DownloadDoneInfo : String;
     VerFoundInfo : TStringList;
      constructor Create(AVersion, AProgName, AUpdateFile, AHomePage,
                                  AUpDateUrl, AVerInfo, ADownloadDoneInfo : String;
                                  AVerFoundInfo : TStrings);
      destructor Destroy;
    end;

implementation

    constructor THeader.Create(AVersion, AProgName, AUpdateFile, AHomePage,
                                              AUpDateUrl, AVerInfo, ADownloadDoneInfo : String;
                                              AVerFoundInfo : TStrings);

    begin
     inherited Create;
     VerFoundInfo:= TStringList.Create;
     VerFoundInfo.Assign(AVerFoundInfo);
     Version:= AVersion;
     ProgName:= AProgName;
     UpdateFile:= AUpdateFile;
     HomePage:= AHomePage;
     UpdateUrl:= AUpDateUrl;
     VerInfo:= AVerInfo;
     DownLoadDOneInfo:= ADownloadDoneInfo;
    end;

    destructor THeader.Destroy;
    begin
      VerFoundInfo.Free;
      inherited Destroy;
    end;

var
 MyHeader: THeader;

procedure WriteUpdate(lzFile : String);
Var
    f : File;
Begin
    AssignFile(F,lzFile);
    reWrite(F,1);
    BlockWrite(F,MyHeader,SizeOf(TMyHeader));
    CloseFile(F);
End;

procedure ReadUpdate(lzFile : String);
Var
    f : File;
Begin
    AssignFile(F,lzFile);
    Reset(F,1);
    BlockRead(F,MyHeader,SizeOf(TMyHeader));
    CloseFile(F);
End;



MyHeader:= TMyHeader.Create(All your fields here);


Shane
0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Oops, it was THeader, not TMyHeader

Shane
0
 
LVL 4

Author Comment

by:dreamvb
Comment Utility
Hi, shaneholmes

First of all thanks for getting ack so quick. I tryed your code provied but with no look well the code compiles find but my data is not saved to the file unless I am doing something wrong.

anyway I provied some code as to my problum. below

Type
    Header = record
    SomeInfo : ShortString;
End;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
Var
    TheHead : Header;
    f : File;
begin
    TheHead.SomeInfo := 'This is some data that needs to exceed 255 chars';
    AssignFile(F,'c:\myfile.txt');
    Rewrite(F,1);
    BlockWrite(F,TheHead,SizeOf(TheHead));
    CloseFile(F);
end;

procedure TForm1.Button2Click(Sender: TObject);
Var
    TheHead : Header;
    F : File;
begin
    AssignFile(F,'C:\myFile.txt');
    Reset(F,1);
    BlockRead(F,TheHead,SizeOf(TheHead));
    CloseFile(F);
    Memo1.Text := TheHead.SomeInfo;
end;


Ok the code works fine for string <255 after that it does not work anyway hope you can help


0
 
LVL 11

Expert Comment

by:shaneholmes
Comment Utility
Type

    THeader = class
    public
     SomeInfo : String;
      constructor Create(ASomeInfo: String);
     end;

implementation

    constructor THeader.Create(ASomeInfo);
    begin
     inherited Create;
     SomeInfo:= ASomeInfo;
    end;


var
 MyHeader: THeader;


procedure SaveToFile(FileName: String);
var
 MemStr: TMemoryStream;
 I: Integer;
begin
 MemStr:= TMemoryStream.Create;
 WriteStreamStr(MemStr, MyHeader.SomeInfo);
 MemStr.SaveToFile(FileName);
 MemStr.Free;
end;

procedure LoadFromFile(FileName: String);
var
 MemStr: TMemoryStream;
begin
 MemStr:= TMemoryStream.Create;
 MemStr.LoadFromFile(FileName);
 MyHeader.SomeInfo:= ReadStreamStr(MemStr);
 MemStr.Free;
end;

0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 
LVL 14

Expert Comment

by:DragonSlayer
Comment Utility
instead of shortstring, you can also consider

Type
    Header = record
    Version : ShortString;
    ProgName : ShortString;
    UpdateFile : ShortString;
    HomePage : ShortString;
    UpDateUrl : ShortString;
    VerFoundInfo : ShortString;
    VerInfo : Array [0 .. 1023] of Char; // 1K bytes should be enough? :-)
    DownloadDoneInfo : ShortString;
End;
0
 
LVL 4

Author Comment

by:dreamvb
Comment Utility
Hi thanks for the exmple but I still cant get the thing to work. I must be doing something wrong. to be fair I never realy played with classes before and this is my first time.

is there any chnage you can provide a small example for me. I am also getting errors back from the ReadStreamStr also.

I know i am draging this question out like but if you can make a small project that will be very helpfull I have also increase the points agian.

Thanks,

0
 
LVL 11

Accepted Solution

by:
shaneholmes earned 150 total points
Comment Utility
If you gibe me an email address, i will send it to you.


Shane

unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, Contnrs;

type

 THeader = class
 public
  SomeInfo : String;
  constructor Create(ASomeInfo: String);
 end;

  TForm1 = class(TForm)
    procedure FormActivate(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
  private
    { Private declarations }
  public
    { Public declarations }
   function ReadStreamStr(Stream : TStream) : string;
   function ReadStreamInt(Stream : TStream) : integer;
   procedure WriteStreamInt(Stream : TStream; Num : integer);
   procedure WriteStreamStr(Stream : TStream; Str : string);
   procedure SaveToFile(FileName: String);
   procedure LoadFromFile(FileName: String);
  end;

var
 Form1: TForm1;
 Headers: TObjectList;

implementation

{$R *.dfm}

constructor THeader.Create(ASomeInfo: STring);
begin
 inherited Create;
 SomeInfo:= ASomeInfo;
end;

procedure TForm1.SaveToFile(FileName: String);
var
 MemStr: TMemoryStream;
 I: Integer;
begin
 MemStr:= TMemoryStream.Create;
 WriteStreamInt(MemStr, Headers.Count);
 for I:= 0 to Headers.Count-1 do
 begin
  WriteStreamStr(MemStr, THeader(Headers[I]).SomeInfo);
 end;
 MemStr.SaveToFile(FileName);
 MemStr.Free;
end;

procedure TForm1.LoadFromFile(FileName: String);
var
 MemStr: TMemoryStream;
 HCount: Integer;
 Header: THeader;
 I: Integer;
begin
 MemStr:= TMemoryStream.Create;
 MemStr.LoadFromFile(FileName);
 HCount:= ReadStreamInt(MemStr);
 for I:= 0 to HCount - 1 do
 begin
  Header:= THeader.Create(ReadStreamStr(MemStr));
  Headers.Add(Header);
 end;
 MemStr.Free;
end;

procedure TForm1.WriteStreamInt(Stream : TStream; Num : integer);
begin
 Stream.Write(Num, SizeOf(Integer));
end;

procedure TForm1.WriteStreamStr(Stream : TStream; Str : string);
var
 StrLen : integer;
begin
 StrLen := Length(Str);
 WriteStreamInt(Stream, StrLen);
 Stream.Write(Str[1], StrLen);
end;

function TForm1.ReadStreamInt(Stream : TStream) : integer;
begin
 Stream.Read(Result, SizeOf(Integer));
end;


function TForm1.ReadStreamStr(Stream : TStream) : string;
var
 StrLen : integer;
begin
 StrLen := ReadStreamInt(Stream);
 if StrLen > -1 then
 begin
  SetLength(Result, StrLen);
  Stream.Read(Result[1], StrLen);
 end
 else
 Result := '';
end;

procedure TForm1.FormActivate(Sender: TObject);
begin
 if fileExists(ExtractFilePath(Application.exeName) + 'Headers.dat') then
  LoadFromFile(ExtractFilePath(Application.exeName) + 'Headers.dat');
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
 SaveToFile(ExtractFilePath(Application.exeName) + 'Headers.dat');
end;

initialization
 Headers:= TObjectList.Create;
 Headers.OwnsObjects:= True;
finalization
 Headers.Free;
end.
0
 
LVL 33

Expert Comment

by:Slick812
Comment Utility
hello dreamvb, inorder to get Long Strings in and out of a File, you will need to record the Length of each String, as well as the characters in the string . .  I put all String types in your Record


type
  Header = record
    Version : String;
    ProgName : String;
    UpdateFile : String;
    HomePage : String;
    UpDateUrl : String;
    VerFoundInfo : String;
    VerInfo : String;
    DownloadDoneInfo : String;
    end;


here is the code for two functions to write and read this record to and from a FileStream - -



procedure HeaderToFStream(const aHeader: Header; FileStrm: TFileStream);
var
Len: Integer;
begin
Len := Length(aHeader.Version);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.Version[1], Len);
Len := Length(aHeader.ProgName);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.ProgName[1], Len);
Len := Length(aHeader.UpdateFile);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.UpdateFile[1], Len);
Len := Length(aHeader.HomePage);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.HomePage[1], Len);
Len := Length(aHeader.UpDateUrl);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.UpDateUrl[1], Len);
Len := Length(aHeader.VerFoundInfo);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.VerFoundInfo[1], Len);
Len := Length(aHeader.DownloadDoneInfo);
FileStrm.WriteBuffer(Len, SizeOf(Len));
if Len > 0 then
  FileStrm.WriteBuffer(aHeader.DownloadDoneInfo[1], Len);
end;

procedure HeaderFromFStream(var aHeader: Header; FileStrm: TFileStream);
var
Len: Integer;
begin
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.Version, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.Version[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.ProgName, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.ProgName[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.UpdateFile, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.UpdateFile[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.HomePage, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.HomePage[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.UpDateUrl, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.UpDateUrl[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.VerFoundInfo, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.VerFoundInfo[1], Len);
FileStrm.ReadBuffer(Len, SizeOf(Len));
SetLength(aHeader.DownloadDoneInfo, Len);
if Len > 0 then
  FileStrm.ReadBuffer(aHeader.DownloadDoneInfo[1], Len);
end;


 //- - - - - - - - - -  Here are Two button Clicks to write and read the header var to a file


procedure TForm1.sbut_RecToFileClick(Sender: TObject);
var
Hed1: Header;
FileStream1: TFileStream;
begin
Hed1.Version := '1.1.1.1';
Hed1.ProgName := 'Hed1';
Hed1.UpdateFile := 'C:\update.file';
Hed1.HomePage := 'www.somehomepage.com';
Hed1.UpDateUrl := 'ftp.charge.you.com/update.zip';
Hed1.VerFoundInfo := 'Found it';
Hed1.VerInfo := 'Version 1.2 more or less';
Hed1.DownloadDoneInfo := 'Whatever goes here';

FileStream1 := TFileStream.Create('E:\header.hed',
                 fmCreate or fmOpenWrite or fmShareDenyWrite);
HeaderToFStream(Hed1, FileStream1);
FreeAndNil(FileStream1);
end;



procedure TForm1.sbut_ReadRecFileClick(Sender: TObject);
var
Hed1: Header;
FileStream1: TFileStream;
begin
FileStream1 := TFileStream.Create('E:\header.hed',
                 fmOpenRead or fmShareDenyWrite);
HeaderFromFStream(Hed1, FileStream1);
FreeAndNil(FileStream1);
ShowMessage(Hed1.UpDateUrl);
end;

 - - - - - - - - - - - - -  - - - - - -  --

ask questions if you need more information
0
 
LVL 4

Author Comment

by:dreamvb
Comment Utility
shaneholmes

Thanks for the code it is now working.

Thank you agian for your help.

Also thanks to all the rest.
0

Featured Post

Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

Join & Write a Comment

Suggested Solutions

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
It is a freely distributed piece of software for such tasks as photo retouching, image composition and image authoring. It works on many operating systems, in many languages.
Sending a Secure fax is easy with eFax Corporate (http://www.enterprise.efax.com). First, Just open a new email message.  In the To field, type your recipient's fax number @efaxsend.com. You can even send a secure international fax — just include t…

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

7 Experts available now in Live!

Get 1:1 Help Now