Total Commander Forum Index Total Commander
Форум поддержки пользователей Total Commander
Сайты: Все о Total Commander | Totalcmd.net | Ghisler.com | RU.TCKB
 
 RulesRules   SearchSearch   FAQFAQ   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Single Post  Topic: Уникальность HANDLE в архиваторном плагине 
Author Message
Mowgli



PostPosted: Sun Jul 05, 2009 23:47    Post subject: Reply with quote

Worros wrote:
Mowgli wrote:
В каком случае TC захочет перечитать заново содержимое архива?
Как минимум при нажатии Ctrl+R.
Похоже, что не так. По Ctrl+R просто выходит из архива наружу и больше не делает ничего.

VadiMGP wrote:
Я тоже люблю отвечать вопросом на вопрос. Но какой в этом смысл в данном случае? Smile
Это был не вопрос, а встречная аналогия в форме вопроса. Ну коли так не нравится, то просто отвечу на самый первый вопрос, который про кирпич. Да, в самом деле нельзя описать кирпич, не описав предвартельно здание. Во-первых, само понятие кирпича становится понятно, только если известно, что такое здание вообще. Во-вторых (и это подтвердит любой строитель), нельзя подобрать кирпич, не зная ничего о здании, которое будет из него построено.
Если с кирпичом это не вполне очевидно, то с элементом механизма это должно было стать более понятно. Функция же по определению является активным элементом (functio = исполнение) и в большей степени подобна части сложного механизма. Соответственно и её назначение как части системы без описания системы понять сложнее. Об этом и была аналогия.

Quote:
Не спецификацию, а рекомендацию.
Я процитирую это место из стандрата:
"If a destructor called during stack unwinding exits with an exception, terminate is called (15.5.1). So destructors should generally catch exceptions and not let them propagate out of the destructor."
Да, написано should. Можно и не следовать этому указанию. Примерно, как можно не следовать указанию "не влезай - убъёт" на высоковольтном щитке.

Quote:
Например, если класс не содержит конструктора по умолчанию, то нет никаких проблем с исключениями в деструкторе.
Откровенно не понял связи между конструктором по умолчанию и исключениями в деструкторе.

Quote:
Я никогда не пользовался STL, так что тебе виднее. Я пользуюсь ATL или MFC. Там дополнительных проверок не требуется.
Я давно не использовал MFC. Проверил, да действительно нулевой указатель интерпретируется как пустая строка. Убогое архитектурное решение.
Убогое, поскольку одному значению придаёт два разных смысла. Нулевой указатель имеет однозначную интерпретацию - память под объект не выделена. Является это логической ошибкой или ошибкой времени выполнения - в сущности не важно, поскольку в обоих случаях на это надо реагировать однозначно, т.е. генерируя ошибку. Пустая же строка - это на самом деле не отсутствие объекта, а объект со вполне конкретным значением. И при такой архитектуре невозможно отличить ситуацию ошибки от значения с пустой строкой. Ошибка маскируется, возможно проявляется где-то в другом месте. Это мизерное удобство, которое ведёт к потенциальнм и серьёзным проблемам.

Quote:
заново начинает делать перебор всех файлов. И когда твой плагин во время очередного вызова ReadHeader возвращает нужный файл, то последующий вызов ProcessFile будет с параметром PK_EXTRACT.
Вот информация, которой мне не хватало для понимания алгоритма. Спасибо! Значит, TC ищет файл, полученный от ReadHeader в ранее построенном списке файлов. Вот теперь всё понятно.

Я набросал псевдокод на C++ для циклов сканирования и распаковки, как я его вижу.

1. Открытие архива:

Code:
tOpenArchiveData arch_data = {};
arch_data.ArcName = archive_path; // полный путь до файла архива
arch_data.OpenMode = PK_OM_LIST; // режим получения списка файлов

HANFLE hArch = OpenArchive(&arch_data);
tHeaderData HeaderData;
while (0 == ReadHeader(hArch, &HeaderData))
{
   file_list.add(HeaderData.FileName); // добавляем очередной файл к списку файлов в архиве
   ProcessFile(hArch, PK_SKIP, 0, 0);
}
CloseArchive(hArch);
// здесь сохраняем полученный список файлов file_list и дескриптор архива hArch до следующего цикла.


2. Распаковка:
Юзер выделил некоторые файлы в списоке файлов. На основе этой информации TC составляет список выделенных файлов selected_file_list, который является подмножеством file_list.
Кроме того, есть ещё и путь назначения dest_dir.

Code:
tOpenArchiveData arch_data = {};
arch_data.ArcName = archive_path; // полный путь до файла архива
arch_data.OpenMode = PK_OM_EXTRACT; // режим распаковки

HANFLE hArch = OpenArchive(&arch_data);

tHeaderData HeaderData;
do
{
   err == ReadHeader(hArch, &HeaderData));
   if (err) break;
   if (selected_file_list.has(HeaderData.FileName))
   {
      selected_file_list.remove(HeaderData.FileName)
      ProcessFile(hArch, PK_EXTRACT, dest_dir, HeaderData.FileName);
      // или так
      // ProcessFile(hArch, PK_EXTRACT, 0, dest_dir + HeaderData.FileName);
   }
   else
   {
      ProcessFile(hArch, PK_SKIP, 0, 0);
   }
}
while (selected_file_list.not_empty());

CloseArchive(hArch);


В общем, плагин я написал. Прошу любить и жаловать.

S.T.A.L.K.E.R. db unpacker 0.0.1 beta
View user's profile Send private message


Powered by phpBB © 2001, 2005 phpBB Group