Находясь в блоке переключателей - PullRequest
1 голос
/ 16 июня 2010

Я видел следующий код, взятый из проекта 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 ]

3 голосов
/ 16 июня 2010

Хотя это устройство Даффа, в этой версии речь идет не о реализации оптимизации развертывания цикла, а о реализации итератора в закодированном потоке Base64. Таким образом, вы можете сделать что-то вроде этого:

Base64Stream stream; // the base64 data

char c;

while ((c == stream->NextChar ()) != 0)
{
  // do something with c
}

В данном коде первый использованный нами переключатель использовался для возврата назад туда, где вышел предыдущий return, а затем while (1) позволяет циклу итерации продолжаться бесконечно. Однако в этой функции нет защиты от переполнения буфера.

В C # есть более точное решение, оператор yield.

3 голосов
/ 16 июня 2010

Как говорит Кенни, этот код выглядит как устройство Даффа. Здесь - это то, что Википедия говорит об этом.

0 голосов
/ 16 июня 2010

Если это попытка реализации устройства Даффа, то он, вероятно, неуместен.

Обратите внимание, что в случае устройства Даффа, как описано в Википедии, цикл конечен, тогда как в представленном выше коде этобесконечный цикл.Единственная возможность для этого - выполнить условие (codechar == code_in + length_in) (хотя code_id и length_in являются неизменными в фрагменте кода).

Я сомневаюсь, что это даже будет работать как устройство Даффа, то есть, что это приведет к правильному расширению цикла компилятором.

...