-const static guchar
-dbase64 [] = {
- 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128,
- 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 62, 128, 128, 128, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 128, 128, 128, 0, 128, 128,
- 128, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 128, 128, 128, 128, 128,
- 128, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51
-};
-
-static MonoArray *
-base64_to_byte_array (gunichar2 *start, gint ilength, MonoBoolean allowWhitespaceOnly)
-{
- gint ignored;
- gint i;
- gunichar2 c;
- gunichar2 last, prev_last, prev2_last;
- gint olength;
- MonoArray *result;
- guchar *res_ptr;
- gint a [4], b [4];
- MonoException *exc;
-
- int havePadding = 0;
- ignored = 0;
- last = prev_last = 0, prev2_last = 0;
- for (i = 0; i < ilength; i++) {
- c = start [i];
- if (c >= sizeof (dbase64)) {
- exc = mono_exception_from_name_msg (mono_get_corlib (),
- "System", "FormatException",
- "Invalid character found.");
- mono_raise_exception (exc);
- } else if (isspace (c)) {
- ignored++;
- } else if (havePadding && c != '=') {
- exc = mono_exception_from_name_msg (mono_get_corlib (),
- "System", "FormatException",
- "Invalid character found.");
- mono_raise_exception (exc);
- } else {
- if (c == '=') havePadding = 1;
- prev2_last = prev_last;
- prev_last = last;
- last = c;
- }
- }
-
- olength = ilength - ignored;
-
- if (allowWhitespaceOnly && olength == 0) {
- return mono_array_new (mono_domain_get (), mono_defaults.byte_class, 0);
- }
-
- if ((olength & 3) != 0 || olength <= 0) {
- exc = mono_exception_from_name_msg (mono_get_corlib (), "System",
- "FormatException", "Invalid length.");
- mono_raise_exception (exc);
- }
-
- if (prev2_last == '=') {
- exc = mono_exception_from_name_msg (mono_get_corlib (), "System", "FormatException", "Invalid format.");
- mono_raise_exception (exc);
- }
-
- olength = (olength * 3) / 4;
- if (last == '=')
- olength--;
-
- if (prev_last == '=')
- olength--;
-
- result = mono_array_new (mono_domain_get (), mono_defaults.byte_class, olength);
- res_ptr = mono_array_addr (result, guchar, 0);
- for (i = 0; i < ilength; ) {
- int k;
-
- for (k = 0; k < 4 && i < ilength;) {
- c = start [i++];
- if (isspace (c))
- continue;
-
- a [k] = (guchar) c;
- if (((b [k] = dbase64 [c]) & 0x80) != 0) {
- exc = mono_exception_from_name_msg (mono_get_corlib (),
- "System", "FormatException",
- "Invalid character found.");
- mono_raise_exception (exc);
- }
- k++;
- }
-
- *res_ptr++ = (b [0] << 2) | (b [1] >> 4);
- if (a [2] != '=')
- *res_ptr++ = (b [1] << 4) | (b [2] >> 2);
- if (a [3] != '=')
- *res_ptr++ = (b [2] << 6) | b [3];
-
- while (i < ilength && isspace (start [i]))
- i++;
- }
-
- return result;
-}
-
-ICALL_EXPORT MonoArray *
-InternalFromBase64String (MonoString *str, MonoBoolean allowWhitespaceOnly)
-{
- MONO_ARCH_SAVE_REGS;
-
- return base64_to_byte_array (mono_string_chars (str),
- mono_string_length (str), allowWhitespaceOnly);
-}
-
-ICALL_EXPORT MonoArray *
-InternalFromBase64CharArray (MonoArray *input, gint offset, gint length)
-{
- MONO_ARCH_SAVE_REGS;
-
- return base64_to_byte_array (mono_array_addr (input, gunichar2, offset),
- length, FALSE);
-}
-