2010-06-16 4 views
1

Я видел следующий код, взятый из libb64 project. Я пытаюсь понять, что цель цикла в то время как в блоке переключателей -Внутри блока переключателя

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); 
     } 
    } 

Что может дать время? Кажется, что так или иначе, всегда коммутатор будет выполнять только один из случаев. Я что-то пропустил?

Спасибо.

+0

Мне кажется, что они просто поменяли оператор while и оператор switch, чтобы вместо этого переключатель был снаружи. – animuson

+5

Похоже на устройство Даффа. – kennytm

+4

Путь слишком сложный, должен быть реорганизован. –

ответ

3

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

Base64Stream stream; // the base64 data 

char c; 

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

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

В C#, есть более аккуратное решение для этого, инструкция yield.

3

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

0

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

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

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