- to_len = CHAR_BYTES (c);
- if (from_len == to_len)
- CHAR_STRING (c, SDATA (obj) + i);
- else
- {
- Faset (obj, make_number (n), make_number (c));
- len += to_len - from_len;
- }
+ MAKE_CHAR_UNIBYTE (c);
+ /* If the char can't be converted to a valid byte, just don't
+ change it. */
+ if (c >= 0 && c < 256)
+ SSET (obj, i, c);
+ }
+ }
+ return obj;
+ }
+ else
+ {
+ EMACS_INT i, i_byte, size = SCHARS (obj);
+ int len;
+ USE_SAFE_ALLOCA;
+ unsigned char *dst, *o;
+ /* Over-allocate by 12%: this is a minor overhead, but should be
+ sufficient in 99.999% of the cases to avoid a reallocation. */
+ EMACS_INT o_size = SBYTES (obj) + SBYTES (obj) / 8 + MAX_MULTIBYTE_LENGTH;
+ SAFE_ALLOCA (dst, void *, o_size);
+ o = dst;
+
+ for (i = i_byte = 0; i < size; i++, i_byte += len)
+ {
+ if ((o - dst) + MAX_MULTIBYTE_LENGTH > o_size)
+ { /* Not enough space for the next char: grow the destination. */
+ unsigned char *old_dst = dst;
+ o_size += o_size; /* Probably overkill, but extremely rare. */
+ SAFE_ALLOCA (dst, void *, o_size);
+ bcopy (old_dst, dst, o - old_dst);
+ o = dst + (o - old_dst);