Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2013.03.22;
Скачать: CL | DM;

Вниз

Не могу найти три отличия в коде   Найти похожие ветки 

 
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;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.048 c
15-1338124044
Loginov Dmitry
2012-05-27 17:07
2013.03.22
Лабораторные работы по языку Pascal. Методические указания


15-1330599411
Pit
2012-03-01 14:56
2013.03.22
Импорт интерфейсов из C# в Delphi


15-1349434291
oxffff
2012-10-05 14:51
2013.03.22
Ищем ABAP стажеров(разработчиков).


15-1346305970
ZeroDivide
2012-08-30 09:52
2013.03.22
Современный смартфон с долгой батарейкой. Есть такие?


15-1353245447
Artem
2012-11-18 17:30
2013.03.22
Простой парсинг