Solved

Put "bytes" in a Unicode string declared variable in Delphi 2009

Posted on 2009-05-20
4
629 Views
Last Modified: 2013-11-23
I am converting an application from Turbo Delphi 2006 to Delphi 2009
Somewhere, I use a "generic" function that receives an array of string in input plus additional database information, and puts these data into some SQL table
Up to now (Turbo Delphi 2006), no problem, even for those strings that in fact contain binary data to be stored in blob fields in the database
But now come Delphi 2009 where all strings are unicode.
I need to keep using that generic function, as well as the "array of unicodestring" mechanism, but I wonder how the calling program can put a string containing bytes (declared as ansistring and filled in with the content of an external binary file for example)  in a unicodestring without those bytes being converted, one way of another
Thanks
0
Comment
Question by:LeTay
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 3
4 Comments
 
LVL 12

Accepted Solution

by:
Hypo earned 500 total points
ID: 24431745
Hi,
I don't know if this is what you are looking for, or if there are som native way of doing this, but this example shows one way of putting data into a unicode string by moving the memory into and out of the string. See the example below.

/Hypo
unit Unit1;
 
interface
 
uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, ComCtrls, StrUtils, StdCtrls, ExtCtrls;
 
type
  TForm1 = class(TForm)
    Memo1: TMemo;
    Button1: TButton;
    Button2: TButton;
    procedure FormCreate(Sender: TObject);
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    FData : Array[0..1000] of Byte;
    FDataPos : Integer;
  end;
 
var
  Form1: TForm1;
 
implementation
 
{$R *.dfm}
 
// Returns the index in the string where the data was inserted...
Function AddBytesToUnicodeString(var Data; Count : Integer; var AText : String) : Integer;
Begin
  Result := Length(AText)+1;
  SetLength(AText, Result+((Count+1) shr 2));
  Move(Data, AText[Result], Count);
End;
 
Procedure GetBytesFromUnicodeString(AText : String; Index : Integer; var Data; Count : Integer);
Begin
  Move(AText[Index], Data, Count);
End;
 
procedure TForm1.FormCreate(Sender: TObject);
var i : Integer;
begin
  // Create a block of random data...
  Randomize;
  for i := 0 to Length(FData)-1 do
    FData[i] := Random(255);
end;
 
// Move FData into Memo1.Text
procedure TForm1.Button1Click(Sender: TObject);
var AText : string;
begin
  AText := Memo1.Text;
  FDataPos := AddBytesToUnicodeString(FData[0], Length(FData), AText);
  Memo1.Text := AText;
end;
 
// Get the Data from the memo into ReadData block
procedure TForm1.Button2Click(Sender: TObject);
var i : Integer;
    ReadData : Array of Byte;
begin
  SetLength(ReadData, Length(FData));
  try
    GetBytesFromUnicodeString(Memo1.Text, FDataPos, ReadData[0], Length(FData));
    // Verify the data we read against the source... 
    for i := 0 to Length(ReadData)-1 do
      if ReadData[i] <> FData[i] then
        raise Exception.Create('Data is not similar: '+IntToStr(i));
    ShowMessage('Data read and restored successfully.');
  finally
    ReadData := nil; 
  end;
end;
 
end.

Open in new window

0
 

Author Comment

by:LeTay
ID: 24431795
Hello Hypo !
You again !
This is nice.
In fact, the "buffer" is initally a ANSIString variable that has been filled in via another function which copy integrally the content of a (binary) file into it
I will look at the code you propose
Thanks !
ps : there may be some delay as I may not come back on this issue very often in the coming weeks
0
 

Author Comment

by:LeTay
ID: 24913747
Hello Hypo
I looked at your code that works fine
I want now to change it a little bit, see code attached
But it does not work
At least I know that in the second procedure, Data needs to be "initialised". I mean, needs the equivalent of SetLength to be performed first, but what should I do to achieve that ?
My final goal is finally to have these procedures in place
=> MoveANSI2UnicodeString
=> MoveUnicodeString2Bytes
Thanks
procedure MoveBytes2UnicodeString(var Data;Length:integer;var UNI:UnicodeString);
begin
 SetLength(UNI,1 + ((Length + 1) shr 2));
 Move(Data,UNI[1],Length);
end;
 
procedure MoveUnicodeString2Bytes(UNI:UnicodeString;var Data);
begin
 Move(UNI[1],Data,Length(UNI) * 2);
end;

Open in new window

0
 

Author Comment

by:LeTay
ID: 24913862
Hello Hypo,
I am here again
The final code I want to use is attached but it fails
I don't understand why
Can you help ?
Thanks
procedure MoveANSI2UnicodeString(var ANSI:ANSIString;UNI:UnicodeString);
begin
 SetLength(UNI,1 + ((Length(ANSI) + 1) shr 2));
 Move(ANSI,UNI[1],Length(ANSI));
end;
 
procedure MoveUnicodeString2ANSI(var UNI:UnicodeString;ANSI:ANSIString);
begin
 SetLength(ANSI,Length(UNI) * 2);
 Move(UNI[1],ANSI,Length(UNI) * 2);
end;

Open in new window

0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…
THe viewer will learn how to use NetBeans IDE 8.0 for Windows to perform CRUD operations on a MySql database.

696 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