Автор Тема: pack() в unix  (Прочитано 4220 раз)

0 Пользователей и 1 Гость просматривают эту тему.

Оффлайн novice2

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 11
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pack() в unix
« : 18 Ноября 2004, 12:15:41 »
Добрый  день.
Столкнулся с тем, что по разному работает pack(). Сокращенный пример:

#!/usr/bin/perl -w
use strict;
my $v = pack(\'Z*\',\'\');
print \'length=\'.length($v).\' data=\'.hexdump($v);

sub hexdump {
    my $data = shift;
    my $res = \'\';
    for(my $i=$[; $i      $res .= sprintf(\'%02x \',ord(substr($data,$i,1)));
    }
    return $res;
}

под windows active perl 5.6.1 выдает
length=1 data=00

под perl 5.005_03 solaris  выдает
length=0 data=

а модуль страдает стандартный, не мой, его исправлять не хотелось бы...
есть идеи?

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
pack() в unix
« Ответ #1 : 18 Ноября 2004, 13:43:40 »
Цитировать
novice2:
есть идеи?

есть. выводи отладочную информацию в hexdump
The documentations is your friend

Оффлайн novice2

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 11
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pack() в unix
« Ответ #2 : 18 Ноября 2004, 14:02:10 »
NeoNox
извини - не понял.
я написал программу. отладил на виндоус - работает. перенес на солярис - не работает. выяснилось, что данные формируются неверно - неправильно работает функция pack(\'Z*\', $str) если $str содержит пустую строчку.pack(\'Z*\'...) должна выдать null-terminated строку (завершенную символом с кодом 0). И когда строка пустая, то должен получиться один байт - 0. Для проверки этого факта и приведен тестовый пример.

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
pack() в unix
« Ответ #3 : 18 Ноября 2004, 14:12:06 »
Цитировать
novice2:
извини - не понял.

поясню кодом:
sub hexdump {
my $data = shift;
my $res;
for(my $i=$[; $iprint $i.length($data)."\\n";
$res .= sprintf(\'%02x \',ord(substr($data,$i,1)));
print "$res\\n";
}
return $res;
}
Что в результате?
The documentations is your friend

Оффлайн novice2

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 11
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pack() в unix
« Ответ #4 : 18 Ноября 2004, 15:25:51 »
появилась возможность проверить на солярисе версию 5.8.5.
оказалось, дело в версии перла. в 5.0 pack() неверно работает для пустой строки. но там, где эта прога будет работать, перл обновить непросто :(

NeoNox
сама hexdump неоднократно проверена.
в таком варианте:
 
#!/usr/bin/perl -w
use strict;
my $v = pack(\'Z*\',\'\');
print \'length=\'.length($v).\' data=\'.hexdump($v);

sub hexdump {
  my $data = shift;
  my $res;
  for(my $i=$[; $i    print \'i=\'.$i.\' length=\'.length($data)."\\n";
    $res .= sprintf(\'%02x \',ord(substr($data,$i,1)));
    print "res=$res\\n";
  }
  return $res;
}

новый перл выдает:
i=0 length=1
res=00
length=1 data=00

а старый:
Use of uninitialized value at t3.pl line 4.
length=0 data=

Оффлайн NeoNox

  • Координатор
  • Глобальный модератор
  • Ветеран
  • *****
  • Сообщений: 3012
  • +0/-0
  • 0
    • Просмотр профиля
pack() в unix
« Ответ #5 : 18 Ноября 2004, 17:36:58 »
novice2 ну новая версия делает для тебя поблажку.
Вот скажи мне, зачем ты в pack передаешь пустое значение?
The documentations is your friend

Оффлайн novice2

  • Заглянувший
  • Новичок
  • *
  • Сообщений: 11
  • +0/-0
  • 0
    • Просмотр профиля
    • http://
pack() в unix
« Ответ #6 : 18 Ноября 2004, 18:01:50 »
NeoNox
ИМХО это не поблажка, а корректнная работа. модификатор Z велит создать строку, завершенную 0. Я передаю пустую строку (ну это я ДОЛЖЕН сделать, там опциональные параметры). И пустая строка должна преобразоваться в 0 символов + байт 0 - итого 1 байт. Новый перл так и работает. Строка, завершенная 0 никогда не может быть короче 1 байта, теоретически. Это стандартный модуль Net::SMPP. И из-за этого бага неверно формируются пакеты протокола :(

 

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28