int base64_decode_block(const char *code_in, int length_in, char *plaintext_out,
			struct base64_decodestate *state_in)
{
	const char *codec = code_in;
	char *plainc = plaintext_out;
	signed char fragmt;

	*plainc = state_in->plainchar;

	switch (state_in->step) {
		while (1) {
			case step_a:
				do {
					if (codec == code_in+length_in) {
						state_in->step = step_a;
						state_in->plainchar = *plainc;
						return plainc - plaintext_out;
					}
					fragmt = base64_decode_value(*codec++);
				} while (fragmt < 0);
				*plainc = (fragmt & 0x03f) << 2;
				/* fall through */
			case step_b:
				do {
					if (codec == code_in+length_in) {
						state_in->step = step_b;
						state_in->plainchar = *plainc;
						return plainc - plaintext_out;
					}
					fragmt = base64_decode_value(*codec++);
				} while (fragmt < 0);
				*plainc++ |= (fragmt & 0x030) >> 4;
				*plainc = (fragmt & 0x00f) << 4;
				/* fall through */
			case step_c:
				do {
					if (codec == code_in+length_in) {
						state_in->step = step_c;
						state_in->plainchar = *plainc;
						return plainc - plaintext_out;
					}
					fragmt = base64_decode_value(*codec++);
				} while (fragmt < 0);
				*plainc++ |= (fragmt & 0x03c) >> 2;
				*plainc = (fragmt & 0x003) << 6;
				/* fall through */
			case step_d:
				do {
					if (codec == code_in+length_in) {
						state_in->step = step_d;
						state_in->plainchar = *plainc;
						return plainc - plaintext_out;
					}
					fragmt = base64_decode_value(*codec++);
				} while (fragmt < 0);
				*plainc++   |= (fragmt & 0x03f);
		}
	}
	/* control should not reach here */
	return plainc - plaintext_out;
}
int base64_decode_block(const char *code_in, int length_in, char *plaintext_out,
			struct base64_decodestate *state_in)
{
	const char *codec = code_in;
	char *plainc = plaintext_out;
	signed char fragmt;

	*plainc = state_in->plainchar;

	switch (state_in->step) {
		while (1) {
			case step_a:
				do {
					if (codec == code_in+length_in) {
						state_in->step = step_a;
						state_in->plainchar = *plainc;
						return plainc - plaintext_out;
					}
					fragmt = base64_decode_value(*codec++);
				} while (fragmt < 0);
				*plainc = (fragmt & 0x03f) << 2;
				 
			case step_b:
				do {
					if (codec == code_in+length_in) {
						state_in->step = step_b;
						state_in->plainchar = *plainc;
						return plainc - plaintext_out;
					}
					fragmt = base64_decode_value(*codec++);
				} while (fragmt < 0);
				*plainc++ |= (fragmt & 0x030) >> 4;
				*plainc = (fragmt & 0x00f) << 4;
				 
			case step_c:
				do {
					if (codec == code_in+length_in) {
						state_in->step = step_c;
						state_in->plainchar = *plainc;
						return plainc - plaintext_out;
					}
					fragmt = base64_decode_value(*codec++);
				} while (fragmt < 0);
				*plainc++ |= (fragmt & 0x03c) >> 2;
				*plainc = (fragmt & 0x003) << 6;
				 
			case step_d:
				do {
					if (codec == code_in+length_in) {
						state_in->step = step_d;
						state_in->plainchar = *plainc;
						return plainc - plaintext_out;
					}
					fragmt = base64_decode_value(*codec++);
				} while (fragmt < 0);
				*plainc++   |= (fragmt & 0x03f);
		}
	}
	 
	return plainc - plaintext_out;
}