2010-06-16 42 views
1

我見過以下代碼,取自libb64 project。 我想了解什麼是開關塊內的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); 
     } 
    } 

什麼可以給一段時間?無論如何,總是交換機只會執行其中一種情況。我錯過了什麼?

謝謝。

+0

在我看來,他們只是交換了while語句和switch語句,以便交換機在外部。 – animuson 2010-06-16 08:46:00

+5

看起來像達夫的設備。 – kennytm 2010-06-16 08:46:04

+4

太複雜,應該重構。 – 2010-06-16 08:49:39

回答

3

雖然這是Duff的設備,但這個版本不是實現循環展開優化,而是實現一個基於Base64編碼流的迭代器。所以,你可以做這樣的事情:

Base64Stream stream; // the base64 data 

char c; 

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

在給定的代碼,我們使用跳回到以前return退出,其中第一開關,然後同時(1)允許迭代循環,以無限期地繼續下去。但是,在此函數中沒有針對緩衝區溢出的保護。

在C#中,有一個更簡潔的解決方案,yield聲明。

3

像肯尼說的,這段代碼看起來像一個達夫的設備。 Here是維基百科對此所說的。

0

如果這是一個實施達夫設備的嘗試,那麼它可能放錯了位置。

請注意,在達夫設備的情況下,如維基百科中所述,循環是有限的,而在上面介紹的代碼中,它是一個永無止境的循環。它完成的唯一可能性是(codechar == code_in + length_in)條件的滿足(儘管code_id和length_in在代碼片段中是不可變的)。

我懷疑它甚至會作爲Duff的設備工作,即它會導致編譯器進行適當的循環擴展。