comparison src/lstream.h @ 5776:65d65b52d608

Pass character count from coding systems to buffer insertion code. src/ChangeLog addition: 2014-01-16 Aidan Kehoe <kehoea@parhasard.net> Pass character count information from the no-conversion and unicode coding systems to the buffer insertion code, making #'find-file on large buffers a little snappier (if ERROR_CHECK_TEXT is not defined). * file-coding.c: * file-coding.c (coding_character_tell): New. * file-coding.c (conversion_coding_stream_description): New. * file-coding.c (no_conversion_convert): Update characters_seen when decoding. * file-coding.c (no_conversion_character_tell): New. * file-coding.c (lstream_type_create_file_coding): Create the no_conversion type with data. * file-coding.c (coding_system_type_create): Make the character_tell method available here. * file-coding.h: * file-coding.h (struct coding_system_methods): Add a new character_tell() method, passing charcount information from the coding systems to the buffer code, avoiding duplicate bytecount-to-charcount work especially with large buffers. * fileio.c (Finsert_file_contents_internal): Update this to pass charcount information to buffer_insert_string_1(), if that is available from the lstream code. * insdel.c: * insdel.c (buffer_insert_string_1): Add a new CCLEN argument, giving the character count of the string to insert. It can be -1 to indicate that te function should work it out itself using bytecount_to_charcount(), as it used to. * insdel.c (buffer_insert_raw_string_1): * insdel.c (buffer_insert_lisp_string_1): * insdel.c (buffer_insert_ascstring_1): * insdel.c (buffer_insert_emacs_char_1): * insdel.c (buffer_insert_from_buffer_1): * insdel.c (buffer_replace_char): Update these functions to use the new calling convention. * insdel.h: * insdel.h (buffer_insert_string): Update this header to reflect the new buffer_insert_string_1() argument. * lstream.c (Lstream_character_tell): New. Return the number of characters *read* and seen by the consumer so far, taking into account the unget buffer, and buffered reading. * lstream.c (Lstream_unread): Update unget_character_count here as appropriate. * lstream.c (Lstream_rewind): Reset unget_character_count here too. * lstream.h: * lstream.h (struct lstream): Provide the character_tell method, add a new field, unget_character_count, giving the number of characters ever passed to Lstream_unread(). Declare Lstream_character_tell(). Make Lstream_ungetc(), which happens to be unused, an inline function rather than a macro, in the course of updating it to modify unget_character_count. * print.c (output_string): Use the new argument to buffer_insert_string_1(). * tests.c: * tests.c (Ftest_character_tell): New test function. * tests.c (syms_of_tests): Make it available. * unicode.c: * unicode.c (struct unicode_coding_stream): * unicode.c (unicode_character_tell): New method. * unicode.c (unicode_convert): Update the character counter as appropriate. * unicode.c (coding_system_type_create_unicode): Make the character_tell method available.
author Aidan Kehoe <kehoea@parhasard.net>
date Thu, 16 Jan 2014 16:27:52 +0000
parents 2dbefd79b3d3
children d2c0ff38ad5c
comparison
equal deleted inserted replaced
5775:4004c3266c09 5776:65d65b52d608
179 /* Indicate whether this stream is seekable -- i.e. it can be rewound. 179 /* Indicate whether this stream is seekable -- i.e. it can be rewound.
180 This method is ignored if the stream does not have a rewind 180 This method is ignored if the stream does not have a rewind
181 method. If this method is not present, the result is determined 181 method. If this method is not present, the result is determined
182 by whether a rewind method is present. */ 182 by whether a rewind method is present. */
183 int (*seekable_p) (Lstream *stream); 183 int (*seekable_p) (Lstream *stream);
184
185 /* Return the number of complete characters read so far. Respects
186 buffering and unget. Returns -1 if unknown or not implemented. */
187 Charcount (*character_tell) (Lstream *stream);
184 /* Perform any additional operations necessary to flush the 188 /* Perform any additional operations necessary to flush the
185 data in this stream. */ 189 data in this stream. */
186 int (*flusher) (Lstream *stream); 190 int (*flusher) (Lstream *stream);
187 /* Perform any additional operations necessary to close this stream down. 191 /* Perform any additional operations necessary to close this stream down.
188 May be NULL. This function is called when Lstream_close() is called 192 May be NULL. This function is called when Lstream_close() is called
248 onto the end and read back from the end. Lstream_read() 252 onto the end and read back from the end. Lstream_read()
249 basically reads backwards from the end to get stuff; Lstream_unread() 253 basically reads backwards from the end to get stuff; Lstream_unread()
250 similarly has to push the data on backwards. */ 254 similarly has to push the data on backwards. */
251 unsigned char *unget_buffer; /* holds characters pushed back onto input */ 255 unsigned char *unget_buffer; /* holds characters pushed back onto input */
252 Bytecount unget_buffer_size; /* allocated size of buffer */ 256 Bytecount unget_buffer_size; /* allocated size of buffer */
253 Bytecount unget_buffer_ind; /* pointer to next buffer spot 257 Bytecount unget_buffer_ind; /* Next buffer spot to write a character */
254 to write a character */ 258
259 Charcount unget_character_count; /* Count of complete characters ever ungot. */
255 260
256 Bytecount byte_count; 261 Bytecount byte_count;
257 int flags; 262 int flags;
258 max_align_t data[1]; 263 max_align_t data[1];
259 }; 264 };
295 int Lstream_flush (Lstream *lstr); 300 int Lstream_flush (Lstream *lstr);
296 int Lstream_flush_out (Lstream *lstr); 301 int Lstream_flush_out (Lstream *lstr);
297 int Lstream_fputc (Lstream *lstr, int c); 302 int Lstream_fputc (Lstream *lstr, int c);
298 int Lstream_fgetc (Lstream *lstr); 303 int Lstream_fgetc (Lstream *lstr);
299 void Lstream_fungetc (Lstream *lstr, int c); 304 void Lstream_fungetc (Lstream *lstr, int c);
300 Bytecount Lstream_read (Lstream *lstr, void *data, 305 Bytecount Lstream_read (Lstream *lstr, void *data, Bytecount size);
301 Bytecount size); 306 Charcount Lstream_character_tell (Lstream *);
302 int Lstream_write (Lstream *lstr, const void *data, 307 int Lstream_write (Lstream *lstr, const void *data,
303 Bytecount size); 308 Bytecount size);
304 int Lstream_was_blocked_p (Lstream *lstr); 309 int Lstream_was_blocked_p (Lstream *lstr);
305 void Lstream_unread (Lstream *lstr, const void *data, Bytecount size); 310 void Lstream_unread (Lstream *lstr, const void *data, Bytecount size);
306 int Lstream_rewind (Lstream *lstr); 311 int Lstream_rewind (Lstream *lstr);
351 unsigned char. This will be the next byte read from the stream. 356 unsigned char. This will be the next byte read from the stream.
352 Any number of bytes can be pushed back and will be read in the 357 Any number of bytes can be pushed back and will be read in the
353 reverse order they were pushed back -- most recent first. (This is 358 reverse order they were pushed back -- most recent first. (This is
354 necessary for consistency -- if there are a number of bytes that 359 necessary for consistency -- if there are a number of bytes that
355 have been unread and I read and unread a byte, it needs to be the 360 have been unread and I read and unread a byte, it needs to be the
356 first to be read again.) This is a macro and so it is very 361 first to be read again.) */
357 efficient. The C argument is only evaluated once but the STREAM 362
358 argument is evaluated more than once. 363 DECLARE_INLINE_HEADER (
359 */ 364 void
360 365 Lstream_ungetc (Lstream *lstr, int c)
361 #define Lstream_ungetc(stream, c) \ 366 )
362 /* Add to the end if it won't overflow buffer; otherwise call the \ 367 {
363 function equivalent */ \ 368 /* Add to the end if it won't overflow buffer; otherwise call the
364 ((stream)->unget_buffer_ind >= (stream)->unget_buffer_size ? \ 369 function equivalent */
365 Lstream_fungetc (stream, c) : \ 370 if (lstr->unget_buffer_ind >= lstr->unget_buffer_size)
366 (void) ((stream)->byte_count--, \ 371 {
367 ((stream)->unget_buffer[(stream)->unget_buffer_ind++] = \ 372 Lstream_fungetc (lstr, c);
368 (unsigned char) (c)))) 373 }
374 else
375 {
376 lstr->byte_count--;
377 lstr->unget_buffer[lstr->unget_buffer_ind] = (unsigned char) (c);
378 lstr->unget_character_count
379 += valid_ibyteptr_p (lstr->unget_buffer + lstr->unget_buffer_ind);
380 lstr->unget_buffer_ind++;
381 }
382 }
369 383
370 #define Lstream_data(stream) ((void *) ((stream)->data)) 384 #define Lstream_data(stream) ((void *) ((stream)->data))
371 #define Lstream_byte_count(stream) ((stream)->byte_count) 385 #define Lstream_byte_count(stream) ((stream)->byte_count)
372 386
373 387