Skip to content

Commit dd1cb49

Browse files
committed
Merge branch 'master' of git://github.com/AlericInglewood/SingularityViewer
2 parents eeeaaa3 + 9ac7a13 commit dd1cb49

File tree

1 file changed

+59
-53
lines changed

1 file changed

+59
-53
lines changed

indra/newview/lllogchat.cpp

Lines changed: 59 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -127,73 +127,79 @@ void LLLogChat::saveHistory(std::string const& filename, std::string line)
127127
}
128128
}
129129

130-
const std::streamoff BUFFER_SIZE(4096);
130+
static long const LOG_RECALL_BUFSIZ = 2048;
131131

132-
// Read a chunk of size from pos in ifstr and prepend it to data
133-
// return that chunk's newline count
134-
U32 read_chunk(llifstream& ifstr, const std::streamoff& pos, U32 size, std::string& data)
132+
void LLLogChat::loadHistory(std::string const& filename , void (*callback)(ELogLineType, std::string, void*), void* userdata)
135133
{
136-
char buffer[BUFFER_SIZE];
137-
ifstr.seekg(pos);
138-
ifstr.read(buffer, size);
139-
data.insert(0, buffer, size);
140-
return std::count(buffer, buffer + size, '\n');
141-
}
142-
143-
void LLLogChat::loadHistory(std::string const& filename , void (*callback)(ELogLineType,std::string,void*), void* userdata)
144-
{
145-
if(!filename.size())
146-
{
147-
llwarns << "Filename is Empty!" << llendl;
148-
return ;
149-
}
150-
151-
llifstream ifstr(makeLogFileName(filename));
152-
if (!ifstr.is_open())
134+
bool filename_empty = filename.empty();
135+
if (filename_empty)
153136
{
154-
callback(LOG_EMPTY,LLStringUtil::null,userdata);
137+
llwarns << "filename is empty!" << llendl;
155138
}
156-
else
139+
else while(1) // So we can use break.
157140
{
141+
// The number of lines to return.
158142
static const LLCachedControl<U32> lines("LogShowHistoryLines", 32);
159-
ifstr.seekg(-1, std::ios_base::end);
160-
if (!lines || !ifstr)
161-
{
162-
callback(LOG_EMPTY,LLStringUtil::null,userdata);
163-
return;
164-
}
143+
if (lines == 0) break;
165144

166-
std::string data;
167-
U32 nlines = 0;
168-
if (ifstr.get() != '\n') // in case file doesn't end with a newline
169-
{
170-
data.push_back('\n');
171-
++nlines;
172-
}
145+
// Open the log file.
146+
LLFILE* fptr = LLFile::fopen(makeLogFileName(filename), "rb");
147+
if (!fptr) break;
173148

174-
// Read BUFFER_SIZE byte chunks until we have enough endlines accumulated
175-
for(std::streamoff pos = ifstr.tellg() - BUFFER_SIZE; nlines < lines+1; pos -= BUFFER_SIZE)
149+
// Set pos to point to the last character of the file, if any.
150+
if (fseek(fptr, 0, SEEK_END)) break;
151+
long pos = ftell(fptr) - 1;
152+
if (pos < 0) break;
153+
154+
char buffer[LOG_RECALL_BUFSIZ];
155+
bool error = false;
156+
int nlines = 0;
157+
while (pos > 0 && nlines < lines)
176158
{
177-
if (pos > 0)
178-
{
179-
nlines += read_chunk(ifstr, pos, BUFFER_SIZE, data);
180-
}
181-
else // Ran out of file read the remaining from the start
159+
// Read the LOG_RECALL_BUFSIZ characters before pos.
160+
size_t size = llmin(LOG_RECALL_BUFSIZ, pos);
161+
pos -= size;
162+
fseek(fptr, pos, SEEK_SET);
163+
size_t len = fread(buffer, 1, size, fptr);
164+
error = len != size;
165+
if (error) break;
166+
// Count the number of newlines in it and set pos to the beginning of the first line to return when we found enough.
167+
for (char const* p = buffer + size - 1; p >= buffer; --p)
182168
{
183-
nlines += read_chunk(ifstr, 0, pos + BUFFER_SIZE, data);
184-
break;
169+
if (*p == '\n')
170+
{
171+
if (++nlines == lines)
172+
{
173+
pos += p - buffer + 1;
174+
break;
175+
}
176+
}
185177
}
186178
}
179+
if (error)
180+
{
181+
fclose(fptr);
182+
break;
183+
}
184+
185+
// Set the file pointer at the first line to return.
186+
fseek(fptr, pos, SEEK_SET);
187187

188-
// Break data into lines
189-
std::istringstream sstr(data);
190-
for (std::string line; nlines > 0 && getline(sstr, line); --nlines)
188+
// Read lines from the file one by one until we reach the end of the file.
189+
while (fgets(buffer, LOG_RECALL_BUFSIZ, fptr))
191190
{
192-
if (nlines <= lines)
193-
{
194-
callback(LOG_LINE, line, userdata);
195-
}
191+
size_t len = strlen(buffer);
192+
if (buffer[len - 1] == '\n') // In case the log file doesn't end on a new-line (is that even possible?)
193+
{
194+
buffer[len - 1] = '\0';
195+
}
196+
callback(LOG_LINE, buffer, userdata);
196197
}
197-
callback(LOG_END,LLStringUtil::null,userdata);
198+
199+
fclose(fptr);
200+
callback(LOG_END, LLStringUtil::null, userdata);
201+
return;
198202
}
203+
callback(LOG_EMPTY, LLStringUtil::null, userdata);
199204
}
205+

0 commit comments

Comments
 (0)