Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
ВнизНе могу найти три отличия в коде Найти похожие ветки
← →
Zheksonz (2012-06-14 12:49) [0]переводил с Си на Делфи следующий код:
__fastcall TWindow::TWindow(TComponent* Owner)
: TForm(Owner)
{
Encoding = TEncoding::UTF8;
ProtocolVersion = 0;
}
//---------------------------------------------------------------------------
void __fastcall TWindow::WriteString(UnicodeString String, TIdTCPClient *TCPClient)
{
Write7BitEncodedInt(Encoding->GetByteCount(String), TCPClient);
TCPClient->Socket->Write(String, Encoding);
}
void __fastcall TWindow::Write7BitEncodedInt(int value, TIdTCPClient *TCPClient)
{
for (; value >= 128; value >>= 7)
TCPClient->Socket->Write((unsigned char)(value | 128));
TCPClient->Socket->Write((unsigned char)value);
}
UnicodeString __fastcall TWindow::ReadString(TIdTCPClient *TCPClient)
{
return TCPClient->Socket->ReadString(Read7BitEncodedInt(TCPClient), Encoding);
}
int __fastcall TWindow::Read7BitEncodedInt(TIdTCPClient *TCPClient)
{
int value = 0, shift = 0, byteval;
while (((byteval = TCPClient->Socket->ReadByte()) & 128) != 0 & shift != 35)
{
value |= ((byteval & 127) << shift);
shift += 7;
}
return (value | (byteval << shift));
}
Вышло следующее:procedure TForm1.WriteString(strng: PAnsiChar; TCPClient: TIdTCPClient);
begin
Write7BitEncodedInt(SizeOf(UTF8Encode(strng)), TCPClient);
TCPClient.Write(UTF8Encode(strng));
end;
procedure TForm1.Write7BitEncodedInt(val: integer; TCPClient: TIdTCPClient);
begin
while val >= 128 do
begin
TCPClient.Write(Char(val or 128));
val := val shr 7;
end;
TCPClient.Write(Char(val));
end;
function TForm1.ReadString(TCPClient: TIdTCPClient): string;
begin
Result := UTF8Encode(TCPClient.ReadString(Read7BitEncodedInt(TCPClient)));
end;
function TForm1.Read7BitEncodedInt(TCPClient: TIdTCPClient): integer;
var
value, shift, byteval: Integer;
bt: Char;
begin
value := 0; shift := 0;
byteval := TCPClient.ReadInteger;
while (((byteval and 128) <> 0) and (shift <> 35)) do
begin
value := value or ((byteval and 127) shl shift);
shift := shift + 7;
byteval := TCPClient.ReadInteger;
end;
end;
Но какой-то неработоспособный код вышел((( Может кому бросится в глаза, где я ошибся?
← →
RWolf © (2012-06-14 13:09) [1]Если исходник делает Socket->ReadByte(), а перевод — ReadInteger, то весьма вероятно, что это не будет работать.
← →
Zheksonz (2012-06-14 13:18) [2]
> RWolf © (14.06.12 13:09) [1]
> Если исходник делает Socket->ReadByte(), а перевод — ReadInteger,
> то весьма вероятно, что это не будет работать.
Да дело в том, что в Делфи вообще нет функции чтения байта((
← →
Zheksonz (2012-06-14 13:18) [3]в смысле непосредственно из TidTCPClienta
← →
RWolf © (2012-06-14 13:22) [4]зато есть ReadBuffer.
← →
DVM © (2012-06-14 16:53) [5]
> Zheksonz
По твоему:Write7BitEncodedInt(SizeOf(UTF8Encode(strng)), TCPClient);
Это аналог:Write7BitEncodedInt(Encoding->GetByteCount(String), TCPClient);
???
← →
Zheksonz (2012-06-14 16:58) [6]В оригинале в integer переменную записывается байт, командой
byteval = TCPClient->Socket->ReadByte()
я пробовалbyteval := TCPClient.ReadInteger;
иTCPClient.ReadBuffer(byteval, 1);
но выдаётся ошибка "socket error # 10054" (((
← →
Zheksonz (2012-06-14 17:01) [7]
> DVM © (14.06.12 16:53) [5]
Я сразу предупреждаю, кто не в курсе ещё, до меня долго доходит... вы главное не нервничайте...
А по вопросу, да, но судя по уровню сарказма в вопросе я неправ(((
← →
Zheksonz (2012-06-14 17:11) [8]DVM © (14.06.12 16:53) [5]
А что не так? и там и там передаётся количество байтов, которое занимает посылаемая команда... Если нет, то в чём я неправ?
← →
ProgRAMmer Dimonych © (2012-06-14 17:16) [9]> [8] Zheksonz (14.06.12 17:11)
В D2010 RawByteString, возвращаемая UTF8Encode() определена как AnsiString. А SizeOf(AnsiString), если не ошибаюсь, есть ничто иное, как 4. Наверное, поэтому и [5].
← →
DVM © (2012-06-14 17:59) [10]
> DVM © (14.06.12 16:53) [5]
>
> А что не так?
1. SizeOf вернет 4, а не количество байт
2. Класс TEncoding есть и в Делфи, начиная с 2009, используй его.
← →
Zheksonz (2012-06-16 13:57) [11]
> DVM © (14.06.12 17:59) [10]
А в Делфи 7 нельзя реализовать подобное, без класса TEncoding? А то как-то специально под него не хочется переустанавливать делфи. Да и не нашёл с ходу более или менее подходящую версию для скачивания(((
← →
Anatoly Podgoretsky © (2012-06-16 15:44) [12]Как же мы жили то до TEncoding?
← →
DVM © (2012-06-16 16:34) [13]
> Zheksonz (16.06.12 13:57) [11]
> А в Делфи 7 нельзя реализовать подобное, без класса TEncoding?
Можно и без, но имхо с ним гораздо удобнее. Тем более, что его и Delphi 7 можно прикрутить. Тут http://www.webdelphi.ru/2011/06/obnovlenie-mlang-dobavlena-podderzhka-delphi-4-xe/ качаешь MLang для Delphi 4 - XE http://www.webdelphi.ru/wp-content/plugins/download-monitor/download.php?id=90 там есть Encodings.pas в нем почти такой же класс как в юникодных делфи.
← →
Zheksonz (2012-06-16 22:01) [14]
> Anatoly Podgoretsky © (16.06.12 15:44) [12]
Надо полагать вы так же жили, ехидничая и умничая.
> DVM © (16.06.12 16:34) [13]
Спасибо, это то что нужно! Жаль у меня нет возможности Вас отблагодарить не только на словах, но и на деле.
← →
Anatoly Podgoretsky © (2012-06-16 23:05) [15]
> Zheksonz (16.06.12 22:01) [14]
Значит для тебя не судьба, придется отказаться от мечты.
← →
Zheksonz (2012-06-16 23:35) [16]
> Anatoly Podgoretsky © (16.06.12 23:05) [15]
Ехидство подтверждающее сказанное мной ранее... а не пришло ли время поумничать?
← →
Zheksonz (2012-06-17 13:11) [17]Чувствую придётся всё-таки установить Delphi 2009 или более позднюю версию...
В общем прикрутил к проекту MLang, всё сделал предельно просто:var
strng: string;
i: Integer;
enc: TEncoding;
begin
strng := "wrwdsfsfsrwer";
i := enc.GetByteCount(strng);
end;
но при запуске этой процедуры выскакивает ошибка EAccessViolation в функции:function TEncoding.GetByteCount(const S: string): Integer;
begin
Result := GetByteCount(PChar(S), Length(S));
end;
ну что сейчас-то не так??? ((((
← →
Inovet © (2012-06-17 16:50) [18]> [17] Zheksonz (17.06.12 13:11)
> Delphi 2009 или более позднюю версию
или более позднюю
← →
sniknik © (2012-06-17 18:02) [19]> ну что сейчас-то не так??? ((((
enc = nil, внутрь процедуры можно не заглядывать, ее для nil нет.
← →
DVM © (2012-06-17 19:10) [20]
> Zheksonz (17.06.12 13:11) [17]
Тебе какая кодировка нужна? Вот ее класс и используй.
TEncoding.UTF8.GetByteCount
← →
Zheksonz (2012-06-17 23:31) [21]Как обычно я протупил, по другому и не скажешь(((
объявленная мной переменнаяenc
, типаTEncoding
и впрямь = nil (спасибо sniknik), отсюда и EAccessViolation
> DVM © (17.06.12 19:10) [20]
А вот TEncoding.UTF8.GetByteCount возвращает количество байтов занимаемое строковой переменной. Спасибо.
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2013.03.22;
Скачать: [xml.tar.bz2];
Память: 0.5 MB
Время: 0.061 c