Находясь в блоке переключателей
Я видел следующий код, взятый из проекта libb64. Я пытаюсь понять, какова цель цикла while внутри блока переключателей -
switch (state_in->step)
{
while (1)
{
case step_a:
do {
if (codechar == code_in+length_in)
{
state_in->step = step_a;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = (char)base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar = (fragment & 0x03f) << 2;
case step_b:
do {
if (codechar == code_in+length_in)
{
state_in->step = step_b;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = (char)base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x030) >> 4;
*plainchar = (fragment & 0x00f) << 4;
case step_c:
do {
if (codechar == code_in+length_in)
{
state_in->step = step_c;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = (char)base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x03c) >> 2;
*plainchar = (fragment & 0x003) << 6;
case step_d:
do {
if (codechar == code_in+length_in)
{
state_in->step = step_d;
state_in->plainchar = *plainchar;
return plainchar - plaintext_out;
}
fragment = (char)base64_decode_value(*codechar++);
} while (fragment < 0);
*plainchar++ |= (fragment & 0x03f);
}
}
Что может дать время? Похоже, в любом случае всегда коммутатор будет выполнять только один из случаев. Я что-то пропустил?
Благодарю.
3 ответа
Хотя это устройство Даффа, эта версия предназначена не для реализации оптимизации развертывания цикла, а для реализации итератора в закодированном потоке Base64. Так что вы можете сделать что-то вроде этого:
Base64Stream stream; // the base64 data
char c;
while ((c == stream->NextChar ()) != 0)
{
// do something with c
}
В данном коде первый использованный нами переключатель использовался для возврата к предыдущему return
выход, а затем while (1) позволяет циклу итерации продолжаться бесконечно. Однако в этой функции нет защиты от переполнения буфера.
В C# есть более точное решение, yield
заявление.
Как говорит Кенни, этот код выглядит как устройство Даффа. Вот что говорит об этом Википедия.
Если это попытка реализовать устройство Даффа, то оно, вероятно, неуместно.
Обратите внимание, что в случае устройства Даффа, как описано в Википедии, цикл является конечным, а в представленном выше коде это бесконечный цикл. Единственная возможность для этого - выполнить условие (codechar == code_in+length_in) (хотя code_id и length_in являются неизменными в фрагменте кода).
Я сомневаюсь, что это даже будет работать как устройство Даффа, то есть, что это приведет к правильному расширению цикла компилятором.