该楼层疑似违规已被系统折叠 隐藏此楼查看此楼
* ************************************************ *)
(* *)
(* 设计:爱吃猪头肉 & Flying Wang 2014-11-08 *)
(* 上面的版权声明请不要移除。 *)
(* *)
(* ************************************************ *)
type
TEncodeType = (etUSASCII, etUTF8, etANSI);
//----------------------------------------------------------
// Detect valid UTF8 sequence.
function DetectUTF8Encoding(const s: TBytes): TEncodeType;
var
c : Byte;
P, EndPtr: PByte;
begin
Result := etUSASCII;
P := PByte(s);
EndPtr := P + Length(s);
// skip leading US-ASCII part.
while P < EndPtr do
begin
if P^ >= $80 then break;
inc(P);
end;
// If all character is US-ASCII, done.
if P = EndPtr then exit;
while P < EndPtr do
begin
c := p^;
case c of
$00..$7F:
inc(P);
$C2..$DF:
if (P+1 < EndPtr)
and ((P+1)^ in [$80..$BF]) then
Inc(P, 2)
else
break;
$E0:
if (P+2 < EndPtr)
and ((P+1)^ in [$A0..$BF])
and ((P+2)^ in [$80..$BF]) then
Inc(P, 3)
else
break;
$E1..$EF:
if (P+2 < EndPtr)
and ((P+1)^ in [$80..$BF])
and ((P+2)^ in [$80..$BF]) then
Inc(P, 3)
else
break;
$F0:
if (P+3 < EndPtr)
and ((P+1)^ in [$90..$BF])
and ((P+2)^ in [$80..$BF])
and ((P+3)^ in [$80..$BF]) then
Inc(P, 4)
else
break;
$F1..$F3:
if (P+3 < EndPtr)
and ((P+1)^ in [$80..$BF])
and ((P+2)^ in [$80..$BF])
and ((P+3)^ in [$80..$BF]) then
Inc(P, 4)
else
break;
$F4:
if (P+3 < EndPtr)
and ((P+1)^ in [$80..$8F])
and ((P+2)^ in [$80..$BF])
and ((P+3)^ in [$80..$BF]) then
Inc(P, 4)
else
break;
else
break;
end;
end;
if P = EndPtr then Result := etUTF8
else Result := etANSI;
end;
// if string contains real UTF8 character, return true.
function IsUTF8String(const s: TBytes): Boolean;
begin
result := DetectUTF8Encoding(s) = etUTF8;
end;
//下述代码 VCL FMX 都可以使用。
procedure TForm1.Button1Click(Sender: TObject);
var
aIdCompressorZLib: TIdCompressorZLib;
gstream,
mstream: TMemoryStream;
ustream: TStringStream;
bstream: TStringStream;
astream: TStringStream;
stream: TStringStream;
idHttpObj: TIdHTTP;
ssss: TStringList;
url: sTring;
ss: string;
aas: ansistring;
rs: TBytes;
aByte: Byte;
isFoundCode: Boolean;
begin
//url := *http://www.5173.com*; //Ansi
//url := *http://sc.5173.com/?question/detail/4981765/0.html*; // UTF8
//url := *http://www.aidian123.com/ajax/get/rate/?username=tb5150803*;
url := *http://wthrcdn.etouch.cn/weather_mini?city=北京*;
url := TIdURI.URLEncode(url); //不编码,中文无法识别。
mstream := TMemoryStream.Create;
try
idHttpObj := TIdHTTP.Create(nil);
try
// Memo1.Lines.Clear;
// Memo1.Lines.add(url);
// Memo1.Lines.add(*正在读取请稍后...*);
// Memo1.Lines.add(**);
// aIdCompressorZLib := TIdCompressorZLib.Create(nil);
// try
// idHttpObj.Compressor := aIdCompressorZLib;
// //idHttpObj.HTTPOptions := idHttpObj.HTTPOptions + [hoForceEncodeParams];
// //idHttpObj.HandleRedirects := True;
// //idHttpObj.Request.UserAgent := *Mozilla/5.0 (Windows NT 5.1) AppleWebKit/537.36 (KHTML, like Gecko) Maxthon/4.0 Chrome/30.0.1599.101 Safari/537.36*;
//
// idHttpObj.Get(url, mstream);
//
// idHttpObj.Compressor := nil;
// finally
// FreeAndNil(aIdCompressorZLib);
// end;
// mstream.Position := 0;
// Memo1.Lines.Clear;
// mstream.Read(aByte, 1);
//
// if aByte = $1F then
// begin
// mstream.Read(aByte, 1);
// if aByte = $8B then
// begin
// mstream.Read(aByte, 1);
// if aByte = $08 then
// begin
// gstream := TMemoryStream.Create;
// try
// mstream.Position := 0;
// aIdCompressorZLib := TIdCompressorZLib.Create(nil);
// try
// aIdCompressorZLib.DecompressGZipStream(mstream, gstream);
// finally
// FreeAndNil(aIdCompressorZLib);
// end;
// mstream.Clear;
// gstream.Position := 0;
// mstream.CopyFrom(gstream, 0);
// finally
// FreeAndNil(gstream);
// end;
// end;
// end;
// end;
// mstream.Position := 0;
// isFoundCode := False;
// mstream.Read(aByte, 1);
// if aByte = $FF then
// begin
// mstream.Read(aByte, 1);
// if aByte = $EF then
// begin
// isFoundCode := True;
// end;
// end
// else if aByte = $EF then
// begin
// mstream.Read(aByte, 1);
// if aByte = $BB then
// begin
// mstream.Read(aByte, 1);
// if aByte = $BF then
// begin
// isFoundCode := True;
// end;
// end
// else if aByte = $FF then
// begin
// isFoundCode := True;
// end;
// end;
// mstream.Position := 0;
mstream.Clear;
// ss := *BOM 自动识别*;
// rs := TEncoding.Unicode.GetBytes(ss);
// mstream.Write(rs, Length(rs));
isFoundCode := False;
aByte := $C4;
mstream.Write(aByte, 1);
aByte := $E3;
mstream.Write(aByte, 1);
aByte := $BA;
mstream.Write(aByte, 1);
aByte := $C3;
mstream.Write(aByte, 1);
if isFoundCode then
begin
//自动识别 BOM
Memo1.Lines.LoadFromStream(mstream);
end
else
begin
//没有 BOM 猜吧。
ustream := TStringStream.Create(**, TEncoding.Unicode);
try
ustream.CopyFrom(mstream, 0);
bstream := TStringStream.Create(**, TEncoding.GetEncoding(936));
try
mstream.Position := 0;
bstream.CopyFrom(mstream, 0);
if ustream.DataString <> bstream.DataString then
begin
end
else
begin
ss := ustream.DataString;
end;
finally
FreeAndNil(bstream);
end;
astream := TStringStream.Create(**, TEncoding.ANSI);
try
mstream.Position := 0;
astream.CopyFrom(mstream, 0);
mstream.Position := 0;
SetLength(rs, mstream.Size);
if mstream.Size > 0 then
begin
FillChar(rs[Low(string)], Length(rs), 0);
mstream.Position := 0;
mstream.Read(rs, mstream.Size);
aas := ansistring(rs);
ss := string(rs);
end;
SetLength(rs, mstream.Size + 1);
FillChar(rs[Low(string)], Length(rs), 0);
mstream.Position := 0;
mstream.Read(rs, mstream.Size);
//Move((@astream.Bytes[0])^, rs[Low(string)], Length(astream.Bytes));
if IsUTF8String(rs) then
begin
stream := TStringStream.Create(**, TEncoding.UTF8);
try
mstream.Position := 0;
stream.CopyFrom(mstream, 0);
ss := stream.DataString;
finally
FreeAndNil(stream);
end;
end
else if true then
begin
ss := astream.DataString;
end
//下面 2 选1.
else if true then
begin
ss := ustream.DataString;
end
else
begin
ss := ustream.DataString;
end;
Memo1.Lines.Text := ss;
finally
FreeAndNil(astream);
end;
finally
FreeAndNil(ustream);
end;
end;
finally
FreeAndNil(idHttpObj);
end;
finally
FreeAndNil(mstream);
end;
end;
end.