123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860 |
- {
- *********************************************************************
- Copyright (C) 2012 Paul Ishenin,
- member of the Free Pascal Development Team
- See the file COPYING.FPC, included in this distribution,
- for details about the copyright.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
- *********************************************************************
- }
- {$ifndef VER2_4}
- { TEncoding }
- class function TEncoding.GetANSI: TEncoding;
- begin
- {$ifdef FPC_HAS_FEATURE_THREADING}
- EnterCriticalSection(FLock);
- try
- {$endif}
- if not Assigned(FStandardEncodings[seAnsi]) then
- begin
- if Assigned(widestringmanager.GetStandardCodePageProc) then
- FStandardEncodings[seAnsi] := TMBCSEncoding.Create(widestringmanager.GetStandardCodePageProc(scpAnsi))
- else
- FStandardEncodings[seAnsi] := TMBCSEncoding.Create(DefaultSystemCodePage);
- end;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- finally
- LeaveCriticalSection(FLock);
- end;
- {$endif}
- Result := FStandardEncodings[seAnsi];
- end;
- function TEncoding.GetAnsiBytes(const S: string): TBytes;
- begin
- if S='' then
- Result := nil
- else
- Result := GetAnsiBytes(S, 1, Length(S));
- end;
- function TEncoding.GetAnsiBytes(const S: string; CharIndex, CharCount: Integer
- ): TBytes;
- begin
- Result := GetAnsiBytes(Pointer(@S[CharIndex]), CharCount);
- end;
- function TEncoding.GetAnsiString(const Bytes: TBytes): string;
- begin
- if Length(Bytes)=0 then
- Result := ''
- else
- Result := GetAnsiString(Bytes, 0, Length(Bytes));
- end;
- function TEncoding.GetAnsiString(const Bytes: TBytes; ByteIndex,
- ByteCount: Integer): string;
- begin
- Result := GetAnsiString(Pointer(@Bytes[ByteIndex]), ByteCount);
- SetCodePage(RawByteString(Result), DefaultSystemCodePage, False);
- end;
- class function TEncoding.GetASCII: TEncoding;
- begin
- {$ifdef FPC_HAS_FEATURE_THREADING}
- EnterCriticalSection(FLock);
- try
- {$endif}
- if not Assigned(FStandardEncodings[seAscii]) then
- FStandardEncodings[seAscii] := TMBCSEncoding.Create(CP_ASCII);
- {$ifdef FPC_HAS_FEATURE_THREADING}
- finally
- LeaveCriticalSection(FLock);
- end;
- {$endif}
- Result := FStandardEncodings[seAscii];
- end;
- class function TEncoding.GetBigEndianUnicode: TEncoding;
- begin
- {$ifdef FPC_HAS_FEATURE_THREADING}
- EnterCriticalSection(FLock);
- try
- {$endif}
- if not Assigned(FStandardEncodings[seBigEndianUnicode]) then
- FStandardEncodings[seBigEndianUnicode] := TBigEndianUnicodeEncoding.Create;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- finally
- LeaveCriticalSection(FLock);
- end;
- {$endif}
- Result := FStandardEncodings[seBigEndianUnicode];
- end;
- class function TEncoding.GetDefault: TEncoding;
- begin
- Result := GetSystemEncoding;
- end;
- class function TEncoding.GetSystemEncoding: TEncoding;
- var
- I: Integer;
- begin
- {$ifdef FPC_HAS_FEATURE_THREADING}
- EnterCriticalSection(FLock);
- try
- {$endif}
- for I := Low(FSystemEncodings) to High(FSystemEncodings) do
- begin
- if FSystemEncodings[I].CodePage=DefaultSystemCodePage then
- begin
- Result := FSystemEncodings[I];
- if I<>Low(FSystemEncodings) then // exchange with first position to find it faster the next time
- begin
- FSystemEncodings[I] := FSystemEncodings[Low(FSystemEncodings)];
- FSystemEncodings[Low(FSystemEncodings)] := Result;
- end;
- Exit;
- end;
- end;
- // not found - create new encoding at first position
- Result := TMBCSEncoding.Create(DefaultSystemCodePage);
- SetLength(FSystemEncodings, Length(FSystemEncodings)+1);
- if High(FSystemEncodings)<>Low(FSystemEncodings) then
- FSystemEncodings[High(FSystemEncodings)] := FSystemEncodings[Low(FSystemEncodings)];
- FSystemEncodings[Low(FSystemEncodings)] := Result;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- finally
- LeaveCriticalSection(FLock);
- end;
- {$endif}
- end;
- class function TEncoding.GetUnicode: TEncoding;
- begin
- {$ifdef FPC_HAS_FEATURE_THREADING}
- EnterCriticalSection(FLock);
- try
- {$endif}
- if not Assigned(FStandardEncodings[seUnicode]) then
- FStandardEncodings[seUnicode] := TUnicodeEncoding.Create;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- finally
- LeaveCriticalSection(FLock);
- end;
- {$endif}
- Result := FStandardEncodings[seUnicode];
- end;
- class function TEncoding.GetUTF7: TEncoding;
- begin
- {$ifdef FPC_HAS_FEATURE_THREADING}
- EnterCriticalSection(FLock);
- try
- {$endif}
- if not Assigned(FStandardEncodings[seUTF7]) then
- FStandardEncodings[seUTF7] := TUTF7Encoding.Create;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- finally
- LeaveCriticalSection(FLock);
- end;
- {$endif}
- Result := FStandardEncodings[seUTF7];
- end;
- class function TEncoding.GetUTF8: TEncoding;
- begin
- {$ifdef FPC_HAS_FEATURE_THREADING}
- EnterCriticalSection(FLock);
- try
- {$endif}
- if not Assigned(FStandardEncodings[seUTF8]) then
- FStandardEncodings[seUTF8] := TUTF8Encoding.Create;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- finally
- LeaveCriticalSection(FLock);
- end;
- {$endif}
- Result := FStandardEncodings[seUTF8];
- end;
- class procedure TEncoding.FreeEncodings;
- var
- E: TStandardEncoding;
- I: Integer;
- begin
- {$ifdef FPC_HAS_FEATURE_THREADING}
- EnterCriticalSection(FLock);
- try
- {$endif}
- for E := Low(FStandardEncodings) to High(FStandardEncodings) do
- FreeAndNil(FStandardEncodings[E]);
- for I := Low(FSystemEncodings) to High(FSystemEncodings) do
- FSystemEncodings[I].Free;
- SetLength(FSystemEncodings, 0);
- {$ifdef FPC_HAS_FEATURE_THREADING}
- finally
- LeaveCriticalSection(FLock);
- end;
- {$endif}
- end;
- class constructor TEncoding.Create;
- var
- E: TStandardEncoding;
- begin
- for E := Low(FStandardEncodings) to High(FStandardEncodings) do
- FStandardEncodings[E] := nil;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- InitCriticalSection(FLock);
- {$endif}
- end;
- class destructor TEncoding.Destroy;
- begin
- FreeEncodings;
- {$ifdef FPC_HAS_FEATURE_THREADING}
- DoneCriticalSection(FLock);
- {$endif}
- end;
- function TEncoding.Clone: TEncoding;
- begin
- Result := nil;
- end;
- class function TEncoding.Convert(Source, Destination: TEncoding;
- const Bytes: TBytes): TBytes;
- begin
- Result := Destination.GetBytes(Source.GetChars(Bytes));
- end;
- class function TEncoding.Convert(Source, Destination: TEncoding;
- const Bytes: TBytes; StartIndex, Count: Integer): TBytes;
- begin
- Result := Destination.GetBytes(Source.GetChars(Bytes, StartIndex, Count));
- end;
- class function TEncoding.IsStandardEncoding(AEncoding: TEncoding): Boolean;
- var
- Encoding: TEncoding;
- begin
- if Assigned(AEncoding) then
- begin
- for Encoding in FStandardEncodings do
- if Encoding = AEncoding then
- Exit(True);
- for Encoding in FSystemEncodings do
- if Encoding = AEncoding then
- Exit(True);
- end;
- Result := False;
- end;
- class function TEncoding.GetBufferEncoding(const Buffer: TBytes; var AEncoding: TEncoding): Integer;
- begin
- Result := GetBufferEncoding(Buffer, AEncoding, Default);
- end;
- class function TEncoding.GetBufferEncoding(const Buffer: TBytes;
- var AEncoding: TEncoding; ADefaultEncoding: TEncoding): Integer;
- function CheckEncoding(AEncoding: TEncoding; out ByteCount: Integer): Boolean;
- var
- Preamble: TBytes;
- begin
- Preamble := AEncoding.GetPreamble;
- ByteCount := Length(Preamble);
- Result := (Length(Buffer) >= ByteCount) and (ByteCount > 0);
- if Result then
- Result := CompareMem(@Preamble[0], @Buffer[0], ByteCount);
- end;
- begin
- if Assigned(AEncoding) then
- begin
- if not CheckEncoding(AEncoding, Result) then
- Result := 0;
- end
- else
- if CheckEncoding(Unicode, Result) then
- AEncoding := Unicode
- else
- if CheckEncoding(BigEndianUnicode, Result) then
- AEncoding := BigEndianUnicode
- else
- if CheckEncoding(UTF8, Result) then
- AEncoding := UTF8
- else
- begin
- AEncoding := ADefaultEncoding;
- Result := 0;
- end;
- end;
- function TEncoding.GetByteCount(const Chars: TUnicodeCharArray): Integer;
- begin
- if Length(Chars)=0 then
- Result := 0
- else
- Result := GetByteCount(Chars, 0, Length(Chars));
- end;
- function TEncoding.GetByteCount(const Chars: TUnicodeCharArray; CharIndex,
- CharCount: Integer): Integer;
- begin
- if (CharCount < 0) or (Length(Chars) < CharCount + CharIndex) then
- raise EEncodingError.CreateFmt(SInvalidCount, [CharCount]);
- if (CharIndex < 0) then
- raise EEncodingError.CreateFmt(SCharacterIndexOutOfBounds, [CharIndex]);
- Result := GetByteCount(@Chars[CharIndex], CharCount);
- end;
- function TEncoding.GetByteCount(const S: UnicodeString): Integer;
- begin
- if S='' then
- Result := 0
- else
- Result := GetByteCount(PUnicodeChar(S), Length(S));
- end;
- function TEncoding.GetByteCount(const S: UnicodeString; CharIndex, CharCount: Integer): Integer;
- begin
- if (CharIndex < 1) then
- raise EEncodingError.CreateFmt(SCharacterIndexOutOfBounds, [CharIndex]);
- if (CharCount < 0) or (Length(S) < CharCount + CharIndex - 1) then
- raise EEncodingError.CreateFmt(SInvalidCount, [CharCount]);
- Result := GetByteCount(@S[CharIndex], CharCount);
- end;
- function TEncoding.GetBytes(const Chars: TUnicodeCharArray): TBytes;
- begin
- SetLength(Result, GetByteCount(Chars));
- if Length(Result)>0 then
- GetBytes(@Chars[0], Length(Chars), @Result[0], Length(Result));
- end;
- function TEncoding.GetBytes(const Chars: TUnicodeCharArray; CharIndex,
- CharCount: Integer): TBytes;
- begin
- if (CharCount < 0) or (Length(Chars) < CharCount + CharIndex) then
- raise EEncodingError.CreateFmt(SInvalidCount, [CharCount]);
- if (CharIndex < 0) then
- raise EEncodingError.CreateFmt(SCharacterIndexOutOfBounds, [CharIndex]);
- SetLength(Result, GetByteCount(Chars, CharIndex, CharCount));
- GetBytes(@Chars[CharIndex], CharCount, @Result[0], Length(Result));
- end;
- function TEncoding.GetBytes(const Chars: TUnicodeCharArray; CharIndex,
- CharCount: Integer; const Bytes: TBytes; ByteIndex: Integer): Integer;
- var
- ByteLen: Integer;
- begin
- ByteLen := Length(Bytes);
- if (ByteLen = 0) and (CharCount > 0) then
- raise EEncodingError.Create(SInvalidDestinationArray);
- if (ByteIndex < 0) or (ByteLen < ByteIndex) then
- raise EEncodingError.CreateFmt(SInvalidDestinationIndex, [ByteIndex]);
- if (CharCount < 0) or (Length(Chars) < CharCount + CharIndex) then
- raise EEncodingError.CreateFmt(SInvalidCount, [CharCount]);
- if (CharIndex < 0) then
- raise EEncodingError.CreateFmt(SCharacterIndexOutOfBounds, [CharIndex]);
- Result := GetBytes(@Chars[CharIndex], CharCount, @Bytes[ByteIndex], ByteLen - ByteIndex);
- end;
- function TEncoding.GetBytes(const S: UnicodeString): TBytes;
- begin
- SetLength(Result, GetByteCount(S));
- if Length(Result)>0 then
- GetBytes(@S[1], Length(S), @Result[0], Length(Result));
- end;
- function TEncoding.GetBytes(const S: UnicodeString; CharIndex, CharCount: Integer;
- const Bytes: TBytes; ByteIndex: Integer): Integer;
- var
- ByteLen: Integer;
- begin
- ByteLen := Length(Bytes);
- if (ByteLen = 0) and (CharCount > 0) then
- raise EEncodingError.Create(SInvalidDestinationArray);
- if (ByteIndex < 0) or (ByteLen < ByteIndex) then
- raise EEncodingError.CreateFmt(SInvalidDestinationIndex, [ByteIndex]);
- if (CharIndex < 1) then
- raise EEncodingError.CreateFmt(SCharacterIndexOutOfBounds, [CharIndex]);
- if (CharCount < 0) or (Length(S) < CharCount + CharIndex - 1) then
- raise EEncodingError.CreateFmt(SInvalidCount, [CharCount]);
- Result := GetBytes(@S[CharIndex], CharCount, @Bytes[ByteIndex], ByteLen - ByteIndex);
- end;
- function TEncoding.GetCharCount(const Bytes: TBytes): Integer;
- begin
- if Length(Bytes)=0 then
- Result := 0
- else
- Result := GetCharCount(@Bytes[0], Length(Bytes));
- end;
- function TEncoding.GetCharCount(const Bytes: TBytes; ByteIndex,
- ByteCount: Integer): Integer;
- begin
- if (ByteIndex < 0) or (Length(Bytes) < ByteIndex) then
- raise EEncodingError.CreateFmt(SInvalidDestinationIndex, [ByteIndex]);
- Result := GetCharCount(@Bytes[ByteIndex], ByteCount);
- end;
- function TEncoding.GetChars(const Bytes: TBytes): TUnicodeCharArray;
- begin
- SetLength(Result, GetCharCount(Bytes));
- if Length(Result)>0 then
- GetChars(@Bytes[0], Length(Bytes), @Result[0], Length(Result));
- end;
- function TEncoding.GetChars(const Bytes: TBytes; ByteIndex, ByteCount: Integer): TUnicodeCharArray;
- begin
- if (ByteIndex < 0) or (Length(Bytes) < ByteIndex) then
- raise EEncodingError.CreateFmt(SInvalidDestinationIndex, [ByteIndex]);
- SetLength(Result, GetCharCount(Bytes, ByteIndex, ByteCount));
- GetChars(@Bytes[ByteIndex], ByteCount, @Result[0], Length(Result));
- end;
- function TEncoding.GetChars(const Bytes: TBytes; ByteIndex, ByteCount: Integer;
- const Chars: TUnicodeCharArray; CharIndex: Integer): Integer;
- var
- CharLen: Integer;
- begin
- if (ByteIndex < 0) or (Length(Bytes) <= ByteIndex) then
- raise EEncodingError.CreateFmt(SInvalidDestinationIndex, [ByteIndex]);
- CharLen := Length(Chars);
- if (CharIndex < 0) or (CharLen <= CharIndex) then
- raise EEncodingError.CreateFmt(SCharacterIndexOutOfBounds, [CharIndex]);
- Result := GetChars(@Bytes[ByteIndex], ByteCount, @Chars[CharIndex], CharLen - CharIndex);
- end;
- class function TEncoding.GetEncoding(CodePage: Integer): TEncoding;
- begin
- case CodePage of
- CP_UTF16: Result := TUnicodeEncoding.Create;
- CP_UTF16BE: Result := TBigEndianUnicodeEncoding.Create;
- CP_UTF7: Result := TUTF7Encoding.Create;
- CP_UTF8: Result := TUTF8Encoding.Create;
- else
- Result := TMBCSEncoding.Create(CodePage);
- end;
- end;
- class function TEncoding.GetEncoding(const EncodingName: UnicodeString): TEncoding;
- var
- ACodePage: TSystemCodePage;
- begin
- ACodePage := CodePageNameToCodePage(AnsiString(EncodingName));
- if ACodePage = $FFFF then
- raise EEncodingError.CreateFmt(SNotValidCodePageName, [EncodingName]);
- Result := TMBCSEncoding.Create(ACodePage);
- end;
- function TEncoding.GetString(const Bytes: TBytes): UnicodeString;
- var
- Chars: TUnicodeCharArray;
- begin
- if Length(Bytes)=0 then
- Result := ''
- else
- begin
- Chars := GetChars(Bytes);
- SetString(Result, PUnicodeChar(Chars), Length(Chars));
- end;
- end;
- function TEncoding.GetString(const Bytes: TBytes; ByteIndex, ByteCount: Integer): UnicodeString;
- var
- Chars: TUnicodeCharArray;
- begin
- Chars := GetChars(Bytes, ByteIndex, ByteCount);
- SetString(Result, PUnicodeChar(Chars), Length(Chars));
- end;
- { TMBCSEncoding }
- function TMBCSEncoding.GetByteCount(Chars: PUnicodeChar; CharCount: Integer): Integer;
- var
- S: RawByteString;
- begin
- widestringmanager.Unicode2AnsiMoveProc(Chars, S, CodePage, CharCount);
- Result := Length(S);
- end;
- function TMBCSEncoding.GetBytes(Chars: PUnicodeChar; CharCount: Integer; Bytes: PByte;
- ByteCount: Integer): Integer;
- var
- S: RawByteString;
- begin
- widestringmanager.Unicode2AnsiMoveProc(Chars, S, CodePage, CharCount);
- Result := Length(S);
- if ByteCount < Result then
- Result := ByteCount;
- if Result > 0 then
- Move(S[1], Bytes[0], Result);
- end;
- function TMBCSEncoding.GetCharCount(Bytes: PByte; ByteCount: Integer): Integer;
- var
- U: UnicodeString;
- begin
- widestringmanager.Ansi2UnicodeMoveProc(PChar(Bytes), CodePage, U, ByteCount);
- Result := Length(U);
- end;
- function TMBCSEncoding.GetChars(Bytes: PByte; ByteCount: Integer; Chars: PUnicodeChar;
- CharCount: Integer): Integer;
- var
- U: UnicodeString;
- begin
- widestringmanager.Ansi2UnicodeMoveProc(PChar(Bytes), CodePage, U, ByteCount);
- Result := Length(U);
- if CharCount < Result then
- Result := CharCount;
- if Result > 0 then
- Move(U[1], Chars[0], Result * SizeOf(UnicodeChar));
- end;
- function TMBCSEncoding.GetCodePage: Cardinal;
- begin
- Result := FCodePage;
- end;
- function TMBCSEncoding.GetEncodingName: UnicodeString;
- begin
- Result := UnicodeString(CodePageToCodePageName(CodePage));
- end;
- constructor TMBCSEncoding.Create;
- begin
- Create(DefaultSystemCodePage, 0, 0);
- end;
- constructor TMBCSEncoding.Create(ACodePage: Integer);
- begin
- Create(ACodePage, 0, 0);
- end;
- constructor TMBCSEncoding.Create(ACodePage, MBToWCharFlags,
- WCharToMBFlags: Integer);
- begin
- FCodePage := ACodePage;
- FMBToWCharFlags := MBToWCharFlags;
- FWCharToMBFlags := WCharToMBFlags;
- case ACodePage of
- CP_UTF7, CP_UTF8, CP_UTF16, CP_UTF16BE: FIsSingleByte := False;
- else
- FIsSingleByte := True;
- end;
- end;
- function TMBCSEncoding.Clone: TEncoding;
- begin
- Result := TMBCSEncoding.Create(FCodePage, FMBToWCharFlags, FWCharToMBFlags);
- end;
- function TMBCSEncoding.GetAnsiBytes(Chars: PChar; CharCount: Integer): TBytes;
- var
- S: RawByteString;
- begin
- SetString(S, Chars, CharCount);
- SetCodePage(S, DefaultSystemCodePage, False);
- SetCodePage(S, GetCodePage, True);
- SetLength(Result, Length(S));
- if Length(S)>0 then
- Move(S[1], Result[0], Length(S));
- end;
- function TMBCSEncoding.GetAnsiString(Bytes: PByte; ByteCount: Integer): string;
- begin
- SetString(Result, Pointer(Bytes), ByteCount);
- SetCodePage(RawByteString(Result), GetCodePage, False);
- SetCodePage(RawByteString(Result), DefaultSystemCodePage, True);
- end;
- function TMBCSEncoding.GetMaxByteCount(CharCount: Integer): Integer;
- begin
- Result := CharCount;
- end;
- function TMBCSEncoding.GetMaxCharCount(ByteCount: Integer): Integer;
- begin
- Result := ByteCount;
- end;
- function TMBCSEncoding.GetPreamble: TBytes;
- begin
- case CodePage of
- CP_UTF8:
- begin
- SetLength(Result, 3);
- Result[0] := $EF;
- Result[1] := $BB;
- Result[2] := $BF;
- end;
- CP_UTF16:
- begin
- SetLength(Result, 2);
- Result[0] := $FF;
- Result[1] := $FE;
- end;
- CP_UTF16BE:
- begin
- SetLength(Result, 2);
- Result[0] := $FE;
- Result[1] := $FF;
- end;
- else
- Result := nil;
- end;
- end;
- { TUTF7Encoding }
- constructor TUTF7Encoding.Create;
- begin
- inherited Create(CP_UTF7);
- FIsSingleByte := False;
- end;
- function TUTF7Encoding.Clone: TEncoding;
- begin
- Result := TUTF7Encoding.Create;
- end;
- function TUTF7Encoding.GetMaxByteCount(CharCount: Integer): Integer;
- begin
- Result := CharCount * 3 + 2;
- end;
- function TUTF7Encoding.GetMaxCharCount(ByteCount: Integer): Integer;
- begin
- Result := ByteCount;
- end;
- { TUTF8Encoding }
- constructor TUTF8Encoding.Create;
- begin
- inherited Create(CP_UTF8);
- FIsSingleByte := False;
- end;
- function TUTF8Encoding.Clone: TEncoding;
- begin
- Result := TUTF8Encoding.Create;
- end;
- function TUTF8Encoding.GetMaxByteCount(CharCount: Integer): Integer;
- begin
- Result := CharCount * 3;
- end;
- function TUTF8Encoding.GetMaxCharCount(ByteCount: Integer): Integer;
- begin
- Result := ByteCount;
- end;
- function TUTF8Encoding.GetPreamble: TBytes;
- begin
- SetLength(Result, 3);
- Result[0] := $EF;
- Result[1] := $BB;
- Result[2] := $BF;
- end;
- { TUnicodeEncoding }
- function TUnicodeEncoding.GetByteCount(Chars: PUnicodeChar; CharCount: Integer): Integer;
- begin
- Result := CharCount * SizeOf(UnicodeChar);
- end;
- function TUnicodeEncoding.GetBytes(Chars: PUnicodeChar; CharCount: Integer;
- Bytes: PByte; ByteCount: Integer): Integer;
- begin
- Result := CharCount * SizeOf(UnicodeChar);
- if ByteCount < Result then
- Result := ByteCount;
- if Result > 0 then
- Move(Chars[0], Bytes[0], Result);
- end;
- function TUnicodeEncoding.GetCharCount(Bytes: PByte; ByteCount: Integer): Integer;
- begin
- Result := ByteCount div SizeOf(UnicodeChar);
- end;
- function TUnicodeEncoding.GetChars(Bytes: PByte; ByteCount: Integer;
- Chars: PUnicodeChar; CharCount: Integer): Integer;
- begin
- Result := ByteCount div 2;
- if CharCount < Result then
- Result := CharCount;
- Move(Bytes[0], Chars[0], Result * SizeOf(UnicodeChar));
- end;
- function TUnicodeEncoding.GetCodePage: Cardinal;
- begin
- Result := CP_UTF16;
- end;
- function TUnicodeEncoding.GetEncodingName: UnicodeString;
- begin
- Result := UnicodeString(CodePageToCodePageName(CodePage));
- end;
- constructor TUnicodeEncoding.Create;
- begin
- inherited Create;
- FIsSingleByte := False;
- FMaxCharSize := SizeOf(UnicodeChar);
- end;
- function TUnicodeEncoding.Clone: TEncoding;
- begin
- Result := TUnicodeEncoding.Create;
- end;
- function TUnicodeEncoding.GetAnsiBytes(Chars: PChar; CharCount: Integer
- ): TBytes;
- var
- U: UnicodeString;
- begin
- widestringmanager.Ansi2UnicodeMoveProc(Chars, DefaultSystemCodePage, U, CharCount);
- SetLength(Result, Length(U)*SizeOf(UnicodeChar));
- if Length(Result)>0 then
- Move(U[1], Result[0], Length(Result));
- end;
- function TUnicodeEncoding.GetAnsiString(Bytes: PByte; ByteCount: Integer
- ): string;
- begin
- widestringmanager.Unicode2AnsiMoveProc(PUnicodeChar(Bytes), RawByteString(Result), DefaultSystemCodePage, ByteCount div SizeOf(UnicodeChar));
- end;
- function TUnicodeEncoding.GetMaxByteCount(CharCount: Integer): Integer;
- begin
- Result := CharCount * SizeOf(UnicodeChar);
- end;
- function TUnicodeEncoding.GetMaxCharCount(ByteCount: Integer): Integer;
- begin
- Result := ByteCount div SizeOf(UnicodeChar);
- end;
- function TUnicodeEncoding.GetPreamble: TBytes;
- begin
- SetLength(Result, 2);
- Result[0] := $FF;
- Result[1] := $FE;
- end;
- { TBigEndianUnicodeEncoding }
- function TBigEndianUnicodeEncoding.GetBytes(Chars: PUnicodeChar; CharCount: Integer;
- Bytes: PByte; ByteCount: Integer): Integer;
- var
- LastByte: PByte;
- begin
- Result := CharCount * SizeOf(UnicodeChar);
- if ByteCount < Result then
- Result := ByteCount;
- LastByte := @Bytes[Result];
- while Bytes < LastByte do
- begin
- Bytes^ := Hi(Word(Chars^));
- inc(Bytes);
- if Bytes < LastByte then
- Bytes^ := Lo(Word(Chars^));
- inc(Bytes);
- inc(Chars);
- end;
- end;
- function TBigEndianUnicodeEncoding.GetChars(Bytes: PByte; ByteCount: Integer;
- Chars: PUnicodeChar; CharCount: Integer): Integer;
- var
- LastChar: PUnicodeChar;
- begin
- Result := ByteCount div SizeOf(UnicodeChar);
- if CharCount < Result then
- Result := CharCount;
- LastChar := @Chars[Result];
- while Chars < LastChar do
- begin
- Chars^ := UnicodeChar(Bytes[1] + Bytes[0] shl 8);
- inc(Bytes, SizeOf(UnicodeChar));
- inc(Chars);
- end;
- end;
- function TBigEndianUnicodeEncoding.GetCodePage: Cardinal;
- begin
- Result := CP_UTF16BE;
- end;
- function TBigEndianUnicodeEncoding.GetEncodingName: UnicodeString;
- begin
- Result := UnicodeString(CodePageToCodePageName(CodePage));
- end;
- function TBigEndianUnicodeEncoding.Clone: TEncoding;
- begin
- Result := TBigEndianUnicodeEncoding.Create;
- end;
- function TBigEndianUnicodeEncoding.GetAnsiBytes(Chars: PChar; CharCount: Integer
- ): TBytes;
- begin
- Result := TEncoding.Unicode.GetAnsiBytes(Chars, CharCount);
- Swap(Result);
- end;
- function TBigEndianUnicodeEncoding.GetAnsiString(Bytes: PByte;
- ByteCount: Integer): string;
- var
- B: TBytes;
- begin
- if ByteCount=0 then
- Exit('');
- SetLength(B, ByteCount);
- Move(Bytes^, B[0], ByteCount);
- Swap(B);
- Result := TEncoding.Unicode.GetAnsiString(PByte(@B[0]), ByteCount);
- end;
- function TBigEndianUnicodeEncoding.GetPreamble: TBytes;
- begin
- SetLength(Result, 2);
- Result[0] := $FE;
- Result[1] := $FF;
- end;
- procedure TBigEndianUnicodeEncoding.Swap(var B: TBytes);
- var
- LastB, I: Integer;
- C: Byte;
- begin
- LastB := Length(B)-1;
- I := 0;
- while I < LastB do
- begin
- C := B[I];
- B[I] := B[I+1];
- B[I+1] := C;
- Inc(I, 2);
- end;
- end;
- {$endif VER2_4}
|