home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Chip 2002 October
/
Chip_2002-10_cd1.bin
/
zkuste
/
delphi
/
kolekce
/
d56
/
FLEXCEL.ZIP
/
XLSAdapter
/
UXlsStrings.pas
< prev
next >
Wrap
Pascal/Delphi Source File
|
2002-06-15
|
6KB
|
228 lines
unit UXlsStrings;
interface
uses XlsMessages, SysUtils,classes, UXlsBaseRecords;
type
TStrLenLength= 1..2;
TCharSize=1..2;
TExcelString= class
private
// Common data
StrLenLength: TStrLenLength; //this stores if it's a one or two bytes length
StrLen: word;
OptionFlags: byte;
WideData: WideString;
ShortData: string;
//Rich text
NumberRichTextFormats: word;
RichTextFormats: PArrayOfByte;
//FarEast
FarEastDataSize: Cardinal;
FarEastData: PArrayOfByte;
function GetValue: WideString;
public
constructor Create(const aStrLenLength: TStrLenLength; var aRecord: TBaseRecord; var Ofs: integer);overload;
constructor Create(const aStrLenLength: TStrLenLength;const s: wideString); overload;
destructor Destroy;override;
procedure SaveToStream(const DataStream: TStream);
function GetCharSize: TCharSize;
function HasRichText: boolean;
function HasFarInfo: boolean;
function Compare(const Str2: TExcelString): integer; //-1 if less, 0 if equal, 1 if more
function TotalSize: int64;
procedure CopyToPtr(const Ptr: PArrayOfByte; const aPos: integer);
property Value: WideString read GetValue;
end;
implementation
{ TExcelString }
function MyWideCompareStr(const S1, S2: WideString): Integer;
var
i:integer;
begin
Result:=0;
if Length(S1)<Length(S2) then Result:=-1 else if Length(S1)>Length(S2) then Result:=1
else
for i:=1 to Length(S1) do
begin
if S1[i]=S2[i] then continue
else if S1[i]<S2[i] then Result:=-1 else Result:=1;
exit;
end;
end;
constructor TExcelString.Create(const aStrLenLength: TStrLenLength; var aRecord: TBaseRecord; var Ofs: integer);
var
StrLenByte: byte;
DestPos: integer;
begin
inherited Create;
StrLenLength:=aStrLenLength;
if StrLenLength=1 then
begin
ReadMem(aRecord, Ofs, StrLenLength, @StrLenByte);
StrLen:=StrLenByte;
end
else ReadMem(aRecord, Ofs, StrLenLength, @StrLen);
ReadMem(aRecord, Ofs, SizeOf(OptionFlags), @OptionFlags);
if HasRichText then ReadMem(aRecord, Ofs, SizeOf(NumberRichTextFormats), @NumberRichTextFormats)
else NumberRichTextFormats:=0;
if HasFarInfo then ReadMem(aRecord, Ofs, SizeOf(FarEastDataSize), @FarEastDataSize)
else FarEastDataSize:=0;
DestPos:=0;
SetLength( ShortData, StrLen);
SetLength( WideData, StrLen);
ReadStr(aRecord, Ofs, ShortData, WideData, OptionFlags, DestPos, StrLen);
if GetCharSize=1 then WideData:='' else ShortData:='';
if NumberRichTextFormats>0 then
begin
GetMem(RichTextFormats, 4* NumberRichTextFormats);
ReadMem(aRecord, Ofs, 4* NumberRichTextFormats, RichTextFormats)
end;
if FarEastDataSize>0 then
begin
GetMem(FarEastData, FarEastDataSize);
ReadMem(aRecord, Ofs, FarEastDataSize, FarEastData)
end;
end;
function TExcelString.Compare(const Str2: TExcelString): integer;
begin
if StrLenLength< Str2.StrLenLength then begin;Result:=-1;exit; end
else if StrLenLength> Str2.StrLenLength then begin;Result:=1;exit; end;
if OptionFlags< Str2.OptionFlags then begin; Result:=-1; exit; end
else if OptionFlags> Str2.OptionFlags then begin; Result:=1; exit; end;
if GetCharSize=1 then Result:=CompareStr(ShortData, Str2.ShortData) else
Result:= MyWideCompareStr(WideData, Str2.WideData);
end;
constructor TExcelString.Create(const aStrLenLength: TStrLenLength;
const s: wideString);
begin
inherited Create;
StrLenLength:=aStrLenLength;
case StrLenLength of
1: if Length(s)> $FF then raise Exception.Create(ErrInvalidStringRecord);
end; //case
StrLen:=Length(s);
OptionFlags:=0;
if IsWide(s) then OptionFlags:=1;
NumberRichTextFormats:=0;
FarEastDataSize:=0;
if GetCharSize= 1 then ShortData:=s else WideData:=s;
end;
destructor TExcelString.Destroy;
begin
FreeMem(FarEastData);
FreeMem(RichTextFormats);
inherited;
end;
function TExcelString.GetCharSize: TCharSize;
begin
if OptionFlags and $1 = 0 then Result:=1 else Result:=2;
end;
function TExcelString.HasFarInfo: boolean;
begin
Result:= OptionFlags and $4 = $4;
end;
function TExcelString.HasRichText: boolean;
begin
Result:= OptionFlags and $8 = $8;
end;
function TExcelString.TotalSize: int64;
begin
Result:=
StrLenLength+
SizeOf(OptionFlags)+
StrLen* GetCharSize;
//Rich text
if HasRichText then
Result:=Result + SizeOf(NumberRichTextFormats)+ 4* NumberRichTextFormats;
//FarEast
if HasFarInfo then
Result:=Result+ SizeOf(FarEastDataSize) + FarEastDataSize;
end;
procedure TExcelString.SaveToStream(const DataStream: TStream);
begin
case StrLenLength of
1: DataStream.Write(StrLen, SizeOf(Byte));
2: DataStream.Write(StrLen, SizeOf(Word));
else raise Exception.Create(ErrInvalidStrLenLength);
end; //case
DataStream.Write(OptionFlags, SizeOf(OptionFlags));
if HasRichText then
DataStream.Write(NumberRichTextFormats, SizeOf(NumberRichTextFormats));
if HasFarInfo then
DataStream.Write(FarEastDataSize, SizeOf(FarEastDataSize));
if GetCharSize= 1 then
if StrLen>0 then DataStream.Write(ShortData[1], Length(ShortData)) else //nothing
else
if StrLen>0 then DataStream.Write(WideData[1], Length(WideData)* SizeOf(WideChar));
if NumberRichTextFormats>0 then
DataStream.Write(RichTextFormats^, 4*NumberRichTextFormats);
if FarEastDataSize>0 then
DataStream.Write(FarEastData^, FarEastDataSize);
end;
procedure TExcelString.CopyToPtr(const Ptr: PArrayOfByte;
const aPos: integer);
var
Ms: TMemoryStream;
begin
//Not the most efficient... but this way we avoid duplicating code
Ms:= TMemoryStream.Create;
try
SaveToStream(Ms);
Ms.Position:=0;
Ms.Read(Ptr[aPos], Ms.Size);
finally
FreeAndNil(Ms);
end;
end;
function TExcelString.GetValue: WideString;
begin
if GetCharSize=1 then Result:= ShortData else Result:= WideData;
end;
end.