@@ -1542,11 +1542,24 @@ bool MCFilesExecPerformReadChunk(MCExecContext &ctxt, int4 p_index, intenum_t p_
15421542
15431543 break ;
15441544 case FU_CHARACTER:
1545- // This loop accumulates codeunits into the buffer and then returns when it crosses a char boundary
1546- // It does this by monitoring the length of the range [index, length(buffer)) for its length in characters
1545+ {
1546+ // In order to make the reading of 1 char faster, we use a temporary,
1547+ // small buffer.
1548+ // We copy the codeunit(s) we read over the last character boundary at
1549+ // the previous reading, and put it into our reading buffer.
1550+ MCAutoStringRef t_read_buffer;
1551+ uindex_t t_initial_length;
1552+
1553+ if (!MCStringMutableCopySubstring (x_buffer, MCRangeMake (p_last_boundary, UINDEX_MAX), &t_read_buffer))
1554+ return false ;
1555+
1556+ // We keep track of the number of codeunit that we have copied for the
1557+ // main buffer.
1558+ t_initial_length = MCStringGetLength (*t_read_buffer);
1559+
15471560 while (true )
15481561 {
1549- uint4 t_codeunit_read = MCFilesExecPerformReadCodeUnit (ctxt, p_index, p_encoding, p_empty_allowed, x_duration, x_stream, x_buffer , r_stat);
1562+ uint4 t_codeunit_read = MCFilesExecPerformReadCodeUnit (ctxt, p_index, p_encoding, p_empty_allowed, x_duration, x_stream, *t_read_buffer , r_stat);
15501563
15511564 if (!t_codeunit_read)
15521565 {
@@ -1565,16 +1578,24 @@ bool MCFilesExecPerformReadChunk(MCExecContext &ctxt, int4 p_index, intenum_t p_
15651578 }
15661579
15671580 MCRange t_cu_range, t_char_range;
1568- t_cu_range = MCRangeMake (p_last_boundary , MCStringGetLength (x_buffer) - p_last_boundary );
1569- MCStringUnmapIndices (x_buffer , kMCCharChunkTypeGrapheme , t_cu_range, t_char_range);
1581+ t_cu_range = MCRangeMake (0 , MCStringGetLength (*t_read_buffer) );
1582+ MCStringUnmapIndices (*t_read_buffer , kMCCharChunkTypeGrapheme , t_cu_range, t_char_range);
15701583
15711584 if (t_char_range . length > 1 )
15721585 {
1573- // The codeunit loaded is now on part of a second character: must end now the loop and mark the position
1586+ // We append the reading buffer MINUS the initial codeunits
1587+ MCAutoStringRef t_new_codeunits;
1588+ if (!MCStringCopySubstring (*t_read_buffer, MCRangeMake (t_initial_length, UINDEX_MAX), &t_new_codeunits)
1589+ || !MCStringAppend (x_buffer, *t_new_codeunits))
1590+ return false ;
1591+
1592+ // The last codeunit is now on part of a new character:
1593+ // we can end here the loop, and appendmust end now the loop and mark the position
15741594 r_new_boundary = MCStringGetLength (x_buffer) - t_codeunit_read;
15751595 break ;
15761596 }
15771597 }
1598+ }
15781599 break ;
15791600
15801601 default :
0 commit comments