diff options
author | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-15 10:33:12 +0000 |
---|---|---|
committer | Denis Vlasenko <vda.linux@googlemail.com> | 2008-07-15 10:33:12 +0000 |
commit | 2132e0221301d2634c265541e62e3efea0cce9d9 (patch) | |
tree | 9b819c8fb79b84660c048027a9fca2ec723db9c0 /libbb/get_line_from_file.c | |
parent | bb13079c8e9ca7bd86193a220baae1befb053fd6 (diff) | |
download | busybox-w32-2132e0221301d2634c265541e62e3efea0cce9d9.tar.gz busybox-w32-2132e0221301d2634c265541e62e3efea0cce9d9.tar.bz2 busybox-w32-2132e0221301d2634c265541e62e3efea0cce9d9.zip |
libbb: experimental faster string reading routines.
Diffstat (limited to 'libbb/get_line_from_file.c')
-rw-r--r-- | libbb/get_line_from_file.c | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/libbb/get_line_from_file.c b/libbb/get_line_from_file.c index 3a76f49a0..7b65ced8d 100644 --- a/libbb/get_line_from_file.c +++ b/libbb/get_line_from_file.c | |||
@@ -67,3 +67,73 @@ char* FAST_FUNC xmalloc_fgetline(FILE *file) | |||
67 | 67 | ||
68 | return c; | 68 | return c; |
69 | } | 69 | } |
70 | |||
71 | /* Faster routines (~twice as fast). +170 bytes. Unused as of 2008-07. | ||
72 | * | ||
73 | * NB: they stop at NUL byte too. | ||
74 | * Performance is important here. Think "grep 50gigabyte_file"... | ||
75 | * Iironically, grep can't use it because of NUL issue. | ||
76 | * We sorely need C lib to provide fgets which reports size! | ||
77 | */ | ||
78 | |||
79 | static char* xmalloc_fgets_internal(FILE *file, int *sizep) | ||
80 | { | ||
81 | int len; | ||
82 | int idx = 0; | ||
83 | char *linebuf = NULL; | ||
84 | |||
85 | while (1) { | ||
86 | char *r; | ||
87 | |||
88 | linebuf = xrealloc(linebuf, idx + 0x100); | ||
89 | r = fgets(&linebuf[idx], 0x100, file); | ||
90 | if (!r) { | ||
91 | /* need to terminate in case this is error | ||
92 | * (EOF puts NUL itself) */ | ||
93 | linebuf[idx] = '\0'; | ||
94 | break; | ||
95 | } | ||
96 | /* stupid. fgets knows the len, it should report it somehow */ | ||
97 | len = strlen(&linebuf[idx]); | ||
98 | idx += len; | ||
99 | if (len != 0xff || linebuf[idx - 1] == '\n') | ||
100 | break; | ||
101 | } | ||
102 | *sizep = idx; | ||
103 | if (idx) { | ||
104 | /* xrealloc(linebuf, idx + 1) is up to caller */ | ||
105 | return linebuf; | ||
106 | } | ||
107 | free(linebuf); | ||
108 | return NULL; | ||
109 | } | ||
110 | |||
111 | /* Get line, remove trailing \n */ | ||
112 | char* FAST_FUNC xmalloc_fgetline_fast(FILE *file) | ||
113 | { | ||
114 | int sz; | ||
115 | char *r = xmalloc_fgets_internal(file, &sz); | ||
116 | if (r && r[sz - 1] == '\n') | ||
117 | r[--sz] = '\0'; | ||
118 | return r; /* not xrealloc(r, sz + 1)! */ | ||
119 | } | ||
120 | |||
121 | #if 0 | ||
122 | char* FAST_FUNC xmalloc_fgets(FILE *file) | ||
123 | { | ||
124 | int sz; | ||
125 | return xmalloc_fgets_internal(file, &sz); | ||
126 | } | ||
127 | |||
128 | /* Get line, remove trailing \n */ | ||
129 | char* FAST_FUNC xmalloc_fgetline(FILE *file) | ||
130 | { | ||
131 | int sz; | ||
132 | char *r = xmalloc_fgets_internal(file, &sz); | ||
133 | if (!r) | ||
134 | return r; | ||
135 | if (r[sz - 1] == '\n') | ||
136 | r[--sz] = '\0'; | ||
137 | return xrealloc(r, sz + 1); | ||
138 | } | ||
139 | #endif | ||