Pregunta

he visto el siguiente código, tomado de la libb64 proyecto . Estoy tratando de entender lo que es el propósito del bucle while dentro del bloque de interruptores -

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

¿Qué puede dar el tiempo? Parece que de todos modos, siempre el interruptor llevará a cabo solamente uno de los casos. ¿Me he perdido algo?

Gracias.

¿Fue útil?

Solución

A pesar de que este es el dispositivo de Duff, esta versión no se trata de implementar una optimización de bucle desenrollado sino más bien para poner en práctica un iterador sobre una base 64 codificado corriente. Así que usted puede hacer algo como esto:

Base64Stream stream; // the base64 data

char c;

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

En el código dado, el primer interruptor nos utiliza para saltar de vuelta a donde la return anterior salió, y entonces el tiempo (1) permite que el bucle de iteración para continuar indefinidamente. Sin embargo, no hay ninguna protección contra una saturación del búfer en esta función.

En C #, hay una solución más ordenado a esto, la declaración yield.

Otros consejos

Al igual que Kenny dice, este código se ve como un dispositivo de Duff. Aquí es lo que dice la Wikipedia al respecto.

Si se trata de un intento de implementar un dispositivo de Duff, entonces es probable que fuera de lugar.

Tenga en cuenta que en el caso del dispositivo de Duff, tal como se describe en Wikipedia, el bucle es finito, mientras que en el código presentado anteriormente es un bucle sin fin. La única posibilidad de que a fin es la satisfacción del (codechar == code_in + length_in) condición (code_id y length_in son inmutables en el fragmento de código, sin embargo).

I duda de que incluso el trabajo como el dispositivo de un Duff, es decir, que dará lugar a la expansión de bucle adecuada por el compilador.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top