diff options
| author | Kenichi Handa | 2000-10-10 02:00:33 +0000 |
|---|---|---|
| committer | Kenichi Handa | 2000-10-10 02:00:33 +0000 |
| commit | caff31d41e1742043403ab69bc68027ecd3120d0 (patch) | |
| tree | 53795bacf32cb4055ed3207e38434063c515e651 /src | |
| parent | 930baf47868ef54656be63ef9d38803680d07a30 (diff) | |
| download | emacs-caff31d41e1742043403ab69bc68027ecd3120d0.tar.gz emacs-caff31d41e1742043403ab69bc68027ecd3120d0.zip | |
(READ_QUADRUPLET_BYTE): Set *NCHARS_RETURN before
returning.
(base64_encode_1): Make it work for a text of multibyte form.
(Fbase64_decode_region): Allocate sufficient memory for multibyte
case. Don't call str_to_multibyte because base64_decode_1
produces correct multibyte form for eight-bit codes.
(Fbase64_decode_string): Adjusted for the change of
base64_decode_1.
(base64_decode_1): New args MULTIBYTE and NCHARS_RETURN. If
MULTIBYTE is nonzero, produce correct multibyte form for eight-bit
codes.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 17 | ||||
| -rw-r--r-- | src/fns.c | 94 |
2 files changed, 79 insertions, 32 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 3f33b0aa244..5dc70468f4d 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,19 @@ | |||
| 1 | 2000-10-10 Kenichi Handa <handa@etl.go.jp> | ||
| 2 | |||
| 3 | * fns.c (READ_QUADRUPLET_BYTE): Set *NCHARS_RETURN before | ||
| 4 | returning. | ||
| 5 | (base64_encode_1): Make it work for a text of multibyte form. | ||
| 6 | (Fbase64_decode_region): Allocate sufficient memory for multibyte | ||
| 7 | case. Don't call str_to_multibyte because base64_decode_1 | ||
| 8 | produces correct multibyte form for eight-bit codes. | ||
| 9 | (Fbase64_decode_string): Adjusted for the change of | ||
| 10 | base64_decode_1. | ||
| 11 | (base64_decode_1): New args MULTIBYTE and NCHARS_RETURN. If | ||
| 12 | MULTIBYTE is nonzero, produce correct multibyte form for eight-bit | ||
| 13 | codes. | ||
| 14 | |||
| 15 | * charset.h (CHAR_STRING): Optimized for single byte characters. | ||
| 16 | |||
| 1 | 2000-10-09 Andreas Schwab <schwab@suse.de> | 17 | 2000-10-09 Andreas Schwab <schwab@suse.de> |
| 2 | 18 | ||
| 3 | * process.c (Fopen_network_stream) [HAVE_GETADDRINFO]: Reset S to | 19 | * process.c (Fopen_network_stream) [HAVE_GETADDRINFO]: Reset S to |
| @@ -17,6 +33,7 @@ | |||
| 17 | (syms_of_msdos): Don't intern and don't staticpro | 33 | (syms_of_msdos): Don't intern and don't staticpro |
| 18 | Qbackground_color and Qforeground_color. | 34 | Qbackground_color and Qforeground_color. |
| 19 | 35 | ||
| 36 | >>>>>>> 1.946 | ||
| 20 | 2000-10-07 Eli Zaretskii <eliz@is.elta.co.il> | 37 | 2000-10-07 Eli Zaretskii <eliz@is.elta.co.il> |
| 21 | 38 | ||
| 22 | * frame.c (Fframe_parameter): For non-windowed frames, if | 39 | * frame.c (Fframe_parameter): For non-windowed frames, if |
| @@ -3189,13 +3189,17 @@ ARGS are passed as extra arguments to the function.") | |||
| 3189 | /* Used by base64_decode_1 to retrieve a non-base64-ignorable | 3189 | /* Used by base64_decode_1 to retrieve a non-base64-ignorable |
| 3190 | character or return retval if there are no characters left to | 3190 | character or return retval if there are no characters left to |
| 3191 | process. */ | 3191 | process. */ |
| 3192 | #define READ_QUADRUPLET_BYTE(retval) \ | 3192 | #define READ_QUADRUPLET_BYTE(retval) \ |
| 3193 | do \ | 3193 | do \ |
| 3194 | { \ | 3194 | { \ |
| 3195 | if (i == length) \ | 3195 | if (i == length) \ |
| 3196 | return (retval); \ | 3196 | { \ |
| 3197 | c = from[i++]; \ | 3197 | if (nchars_return) \ |
| 3198 | } \ | 3198 | *nchars_return = nchars; \ |
| 3199 | return (retval); \ | ||
| 3200 | } \ | ||
| 3201 | c = from[i++]; \ | ||
| 3202 | } \ | ||
| 3199 | while (IS_BASE64_IGNORABLE (c)) | 3203 | while (IS_BASE64_IGNORABLE (c)) |
| 3200 | 3204 | ||
| 3201 | /* Don't use alloca for regions larger than this, lest we overflow | 3205 | /* Don't use alloca for regions larger than this, lest we overflow |
| @@ -3252,7 +3256,7 @@ static short base64_char_to_value[128] = | |||
| 3252 | 3256 | ||
| 3253 | 3257 | ||
| 3254 | static int base64_encode_1 P_ ((const char *, char *, int, int, int)); | 3258 | static int base64_encode_1 P_ ((const char *, char *, int, int, int)); |
| 3255 | static int base64_decode_1 P_ ((const char *, char *, int)); | 3259 | static int base64_decode_1 P_ ((const char *, char *, int, int, int *)); |
| 3256 | 3260 | ||
| 3257 | DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region, | 3261 | DEFUN ("base64-encode-region", Fbase64_encode_region, Sbase64_encode_region, |
| 3258 | 2, 3, "r", | 3262 | 2, 3, "r", |
| @@ -3386,9 +3390,9 @@ base64_encode_1 (from, to, length, line_break, multibyte) | |||
| 3386 | if (multibyte) | 3390 | if (multibyte) |
| 3387 | { | 3391 | { |
| 3388 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); | 3392 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); |
| 3389 | if (bytes > 1) | 3393 | if (c >= 256) |
| 3390 | return -1; | 3394 | return -1; |
| 3391 | i++; | 3395 | i += bytes; |
| 3392 | } | 3396 | } |
| 3393 | else | 3397 | else |
| 3394 | c = from[i++]; | 3398 | c = from[i++]; |
| @@ -3424,9 +3428,9 @@ base64_encode_1 (from, to, length, line_break, multibyte) | |||
| 3424 | if (multibyte) | 3428 | if (multibyte) |
| 3425 | { | 3429 | { |
| 3426 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); | 3430 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); |
| 3427 | if (bytes > 1) | 3431 | if (c >= 256) |
| 3428 | return -1; | 3432 | return -1; |
| 3429 | i++; | 3433 | i += bytes; |
| 3430 | } | 3434 | } |
| 3431 | else | 3435 | else |
| 3432 | c = from[i++]; | 3436 | c = from[i++]; |
| @@ -3446,9 +3450,9 @@ base64_encode_1 (from, to, length, line_break, multibyte) | |||
| 3446 | if (multibyte) | 3450 | if (multibyte) |
| 3447 | { | 3451 | { |
| 3448 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); | 3452 | c = STRING_CHAR_AND_LENGTH (from + i, length - i, bytes); |
| 3449 | if (bytes > 1) | 3453 | if (c >= 256) |
| 3450 | return -1; | 3454 | return -1; |
| 3451 | i++; | 3455 | i += bytes; |
| 3452 | } | 3456 | } |
| 3453 | else | 3457 | else |
| 3454 | c = from[i++]; | 3458 | c = from[i++]; |
| @@ -3469,11 +3473,12 @@ If the region can't be decoded, signal an error and don't modify the buffer.") | |||
| 3469 | (beg, end) | 3473 | (beg, end) |
| 3470 | Lisp_Object beg, end; | 3474 | Lisp_Object beg, end; |
| 3471 | { | 3475 | { |
| 3472 | int ibeg, iend, length; | 3476 | int ibeg, iend, length, allength; |
| 3473 | char *decoded; | 3477 | char *decoded; |
| 3474 | int old_pos = PT; | 3478 | int old_pos = PT; |
| 3475 | int decoded_length; | 3479 | int decoded_length; |
| 3476 | int inserted_chars; | 3480 | int inserted_chars; |
| 3481 | int multibyte = !NILP (current_buffer->enable_multibyte_characters); | ||
| 3477 | 3482 | ||
| 3478 | validate_region (&beg, &end); | 3483 | validate_region (&beg, &end); |
| 3479 | 3484 | ||
| @@ -3481,34 +3486,35 @@ If the region can't be decoded, signal an error and don't modify the buffer.") | |||
| 3481 | iend = CHAR_TO_BYTE (XFASTINT (end)); | 3486 | iend = CHAR_TO_BYTE (XFASTINT (end)); |
| 3482 | 3487 | ||
| 3483 | length = iend - ibeg; | 3488 | length = iend - ibeg; |
| 3484 | /* We need to allocate enough room for decoding the text. */ | 3489 | |
| 3485 | if (length <= MAX_ALLOCA) | 3490 | /* We need to allocate enough room for decoding the text. If we are |
| 3486 | decoded = (char *) alloca (length); | 3491 | working on a multibyte buffer, each decoded code may occupy at |
| 3492 | most two bytes. */ | ||
| 3493 | allength = multibyte ? length * 2 : length; | ||
| 3494 | if (allength <= MAX_ALLOCA) | ||
| 3495 | decoded = (char *) alloca (allength); | ||
| 3487 | else | 3496 | else |
| 3488 | decoded = (char *) xmalloc (length); | 3497 | decoded = (char *) xmalloc (allength); |
| 3489 | 3498 | ||
| 3490 | move_gap_both (XFASTINT (beg), ibeg); | 3499 | move_gap_both (XFASTINT (beg), ibeg); |
| 3491 | decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length); | 3500 | decoded_length = base64_decode_1 (BYTE_POS_ADDR (ibeg), decoded, length, |
| 3492 | if (decoded_length > length) | 3501 | multibyte, &inserted_chars); |
| 3502 | if (decoded_length > allength) | ||
| 3493 | abort (); | 3503 | abort (); |
| 3494 | 3504 | ||
| 3495 | if (decoded_length < 0) | 3505 | if (decoded_length < 0) |
| 3496 | { | 3506 | { |
| 3497 | /* The decoding wasn't possible. */ | 3507 | /* The decoding wasn't possible. */ |
| 3498 | if (length > MAX_ALLOCA) | 3508 | if (allength > MAX_ALLOCA) |
| 3499 | xfree (decoded); | 3509 | xfree (decoded); |
| 3500 | error ("Invalid base64 data"); | 3510 | error ("Invalid base64 data"); |
| 3501 | } | 3511 | } |
| 3502 | 3512 | ||
| 3503 | inserted_chars = decoded_length; | ||
| 3504 | if (!NILP (current_buffer->enable_multibyte_characters)) | ||
| 3505 | decoded_length = str_to_multibyte (decoded, length, decoded_length); | ||
| 3506 | |||
| 3507 | /* Now we have decoded the region, so we insert the new contents | 3513 | /* Now we have decoded the region, so we insert the new contents |
| 3508 | and delete the old. (Insert first in order to preserve markers.) */ | 3514 | and delete the old. (Insert first in order to preserve markers.) */ |
| 3509 | TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg); | 3515 | TEMP_SET_PT_BOTH (XFASTINT (beg), ibeg); |
| 3510 | insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0); | 3516 | insert_1_both (decoded, inserted_chars, decoded_length, 0, 1, 0); |
| 3511 | if (length > MAX_ALLOCA) | 3517 | if (allength > MAX_ALLOCA) |
| 3512 | xfree (decoded); | 3518 | xfree (decoded); |
| 3513 | /* Delete the original text. */ | 3519 | /* Delete the original text. */ |
| 3514 | del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars, | 3520 | del_range_both (PT, PT_BYTE, XFASTINT (end) + inserted_chars, |
| @@ -3544,7 +3550,8 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string, | |||
| 3544 | else | 3550 | else |
| 3545 | decoded = (char *) xmalloc (length); | 3551 | decoded = (char *) xmalloc (length); |
| 3546 | 3552 | ||
| 3547 | decoded_length = base64_decode_1 (XSTRING (string)->data, decoded, length); | 3553 | decoded_length = base64_decode_1 (XSTRING (string)->data, decoded, length, |
| 3554 | STRING_MULTIBYTE (string), NULL); | ||
| 3548 | if (decoded_length > length) | 3555 | if (decoded_length > length) |
| 3549 | abort (); | 3556 | abort (); |
| 3550 | else if (decoded_length >= 0) | 3557 | else if (decoded_length >= 0) |
| @@ -3560,16 +3567,24 @@ DEFUN ("base64-decode-string", Fbase64_decode_string, Sbase64_decode_string, | |||
| 3560 | return decoded_string; | 3567 | return decoded_string; |
| 3561 | } | 3568 | } |
| 3562 | 3569 | ||
| 3570 | /* Base64-decode the data at FROM of LENGHT bytes into TO. If | ||
| 3571 | MULTIBYTE is nonzero, the decoded result should be in multibyte | ||
| 3572 | form. If NCHARS_RETRUN is not NULL, store the number of produced | ||
| 3573 | characters in *NCHARS_RETURN. */ | ||
| 3574 | |||
| 3563 | static int | 3575 | static int |
| 3564 | base64_decode_1 (from, to, length) | 3576 | base64_decode_1 (from, to, length, multibyte, nchars_return) |
| 3565 | const char *from; | 3577 | const char *from; |
| 3566 | char *to; | 3578 | char *to; |
| 3567 | int length; | 3579 | int length; |
| 3580 | int multibyte; | ||
| 3581 | int *nchars_return; | ||
| 3568 | { | 3582 | { |
| 3569 | int i = 0; | 3583 | int i = 0; |
| 3570 | char *e = to; | 3584 | char *e = to; |
| 3571 | unsigned char c; | 3585 | unsigned char c; |
| 3572 | unsigned long value; | 3586 | unsigned long value; |
| 3587 | int nchars = 0; | ||
| 3573 | 3588 | ||
| 3574 | while (1) | 3589 | while (1) |
| 3575 | { | 3590 | { |
| @@ -3589,7 +3604,12 @@ base64_decode_1 (from, to, length) | |||
| 3589 | return -1; | 3604 | return -1; |
| 3590 | value |= base64_char_to_value[c] << 12; | 3605 | value |= base64_char_to_value[c] << 12; |
| 3591 | 3606 | ||
| 3592 | *e++ = (unsigned char) (value >> 16); | 3607 | c = (unsigned char) (value >> 16); |
| 3608 | if (multibyte) | ||
| 3609 | e += CHAR_STRING (c, e); | ||
| 3610 | else | ||
| 3611 | *e++ = c; | ||
| 3612 | nchars++; | ||
| 3593 | 3613 | ||
| 3594 | /* Process third byte of a quadruplet. */ | 3614 | /* Process third byte of a quadruplet. */ |
| 3595 | 3615 | ||
| @@ -3608,7 +3628,12 @@ base64_decode_1 (from, to, length) | |||
| 3608 | return -1; | 3628 | return -1; |
| 3609 | value |= base64_char_to_value[c] << 6; | 3629 | value |= base64_char_to_value[c] << 6; |
| 3610 | 3630 | ||
| 3611 | *e++ = (unsigned char) (0xff & value >> 8); | 3631 | c = (unsigned char) (0xff & value >> 8); |
| 3632 | if (multibyte) | ||
| 3633 | e += CHAR_STRING (c, e); | ||
| 3634 | else | ||
| 3635 | *e++ = c; | ||
| 3636 | nchars++; | ||
| 3612 | 3637 | ||
| 3613 | /* Process fourth byte of a quadruplet. */ | 3638 | /* Process fourth byte of a quadruplet. */ |
| 3614 | 3639 | ||
| @@ -3621,7 +3646,12 @@ base64_decode_1 (from, to, length) | |||
| 3621 | return -1; | 3646 | return -1; |
| 3622 | value |= base64_char_to_value[c]; | 3647 | value |= base64_char_to_value[c]; |
| 3623 | 3648 | ||
| 3624 | *e++ = (unsigned char) (0xff & value); | 3649 | c = (unsigned char) (0xff & value); |
| 3650 | if (multibyte) | ||
| 3651 | e += CHAR_STRING (c, e); | ||
| 3652 | else | ||
| 3653 | *e++ = c; | ||
| 3654 | nchars++; | ||
| 3625 | } | 3655 | } |
| 3626 | } | 3656 | } |
| 3627 | 3657 | ||