Revision: 1051
Author: [email protected]
Date: Tue Feb 9 06:52:17 2010
Log: Improve NYTP_gets() so that it will also work on compressed input
streams.
http://code.google.com/p/perl-devel-nytprof/source/detail?r=1051
Modified:
/trunk/FileHandle.xs
=======================================
--- /trunk/FileHandle.xs Mon Feb 8 08:11:41 2010
+++ /trunk/FileHandle.xs Tue Feb 9 06:52:17 2010
@@ -191,36 +191,6 @@
return file;
}
-
-/* This isn't exactly fgets. It will resize the buffer as needed, and
returns
- a pointer to one beyond the read data (usually the terminating '\0'), or
- NULL if it hit error/EOF */
-
-char *
-NYTP_gets(NYTP_file ifile, char **buffer_p, size_t *len_p) {
- char *buffer = *buffer_p;
- size_t len = *len_p;
- size_t prev_len = 0;
-
- CROAK_IF_NOT_STDIO(ifile, "NYTP_gets");
-
- while(fgets(buffer + prev_len, len - prev_len, ifile->file)) {
- /* We know that there are no '\0' bytes in the part we've already
- read, so don't bother running strlen() over that part. */
- char *end = buffer + prev_len + strlen(buffer + prev_len);
- if (end[-1] == '\n') {
- *buffer_p = buffer;
- *len_p = len;
- return end;
- }
- prev_len = len - 1; /* -1 to take off the '\0' at the end */
- len *= 2;
- buffer = saferealloc(buffer, len);
- }
- *buffer_p = buffer;
- *len_p = len;
- return NULL;
-}
#ifdef HAS_ZLIB
@@ -337,6 +307,82 @@
}
return len;
}
+
+/* This isn't exactly fgets. It will resize the buffer as needed, and
returns
+ a pointer to one beyond the read data (usually the terminating '\0'), or
+ NULL if it hit error/EOF */
+
+char *
+NYTP_gets(NYTP_file ifile, char **buffer_p, size_t *len_p) {
+ char *buffer = *buffer_p;
+ size_t len = *len_p;
+ size_t prev_len = 0;
+
+#ifdef HAS_ZLIB
+ if (FILE_STATE(ifile) == NYTP_FILE_INFLATE) {
+ while (1) {
+ const unsigned char *const p = ifile->large_buffer +
ifile->count;
+ const unsigned int remaining = ((unsigned char *)
ifile->zs.next_out) - p;
+ unsigned char *const nl = memchr(p, '\n', remaining);
+ size_t got;
+ size_t want;
+ size_t extra;
+
+ if (nl) {
+ want = nl + 1 - p;
+ extra = want + 1; /* 1 more to add a \0 */
+ } else {
+ want = extra = remaining;
+ }
+
+ if (extra > len - prev_len) {
+ prev_len = len;
+ len += extra;
+ buffer = saferealloc(buffer, len);
+ }
+
+ got = NYTP_read_unchecked(ifile, buffer + prev_len, want);
+ if (got != want)
+ croak("NYTP_gets unexpected short read. got %lu,
expected %lu\n",
+ (unsigned long)got, (unsigned long)want);
+
+ if (nl) {
+ buffer[prev_len + want] = '\0';
+ *buffer_p = buffer;
+ *len_p = len;
+ return buffer + prev_len + want;
+ }
+ if (ifile->zlib_at_eof) {
+ *buffer_p = buffer;
+ *len_p = len;
+ return NULL;
+ }
+ grab_input(ifile);
+ }
+ }
+#endif
+ if (FILE_STATE(ifile) != NYTP_FILE_STDIO) {
+ compressed_io_croak(ifile, "NYTP_gets");
+ return 0;
+ }
+
+ while(fgets(buffer + prev_len, len - prev_len, ifile->file)) {
+ /* We know that there are no '\0' bytes in the part we've already
+ read, so don't bother running strlen() over that part. */
+ char *end = buffer + prev_len + strlen(buffer + prev_len);
+ if (end[-1] == '\n') {
+ *buffer_p = buffer;
+ *len_p = len;
+ return end;
+ }
+ prev_len = len - 1; /* -1 to take off the '\0' at the end */
+ len *= 2;
+ buffer = saferealloc(buffer, len);
+ }
+ *buffer_p = buffer;
+ *len_p = len;
+ return NULL;
+}
#ifdef HAS_ZLIB
--
You've received this message because you are subscribed to
the Devel::NYTProf Development User group.
Group hosted at: http://groups.google.com/group/develnytprof-dev
Project hosted at: http://perl-devel-nytprof.googlecode.com
CPAN distribution: http://search.cpan.org/dist/Devel-NYTProf
To post, email: [email protected]
To unsubscribe, email: [email protected]