xref: /glogg/tests/testlogfiltereddata.cpp (revision 7d862d7eb72f975a348b2f6e3520b8fef56f2cc7)
12851c541SNicolas Bonnefon /*
22851c541SNicolas Bonnefon  * Copyright (C) 2009, 2010 Nicolas Bonnefon and other contributors
32851c541SNicolas Bonnefon  *
42851c541SNicolas Bonnefon  * This file is part of glogg.
52851c541SNicolas Bonnefon  *
62851c541SNicolas Bonnefon  * glogg is free software: you can redistribute it and/or modify
72851c541SNicolas Bonnefon  * it under the terms of the GNU General Public License as published by
82851c541SNicolas Bonnefon  * the Free Software Foundation, either version 3 of the License, or
92851c541SNicolas Bonnefon  * (at your option) any later version.
102851c541SNicolas Bonnefon  *
112851c541SNicolas Bonnefon  * glogg is distributed in the hope that it will be useful,
122851c541SNicolas Bonnefon  * but WITHOUT ANY WARRANTY; without even the implied warranty of
132851c541SNicolas Bonnefon  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
142851c541SNicolas Bonnefon  * GNU General Public License for more details.
152851c541SNicolas Bonnefon  *
162851c541SNicolas Bonnefon  * You should have received a copy of the GNU General Public License
172851c541SNicolas Bonnefon  * along with glogg.  If not, see <http://www.gnu.org/licenses/>.
182851c541SNicolas Bonnefon  */
192851c541SNicolas Bonnefon 
20f35c72b9SNicolas Bonnefon #include <QSignalSpy>
21f35c72b9SNicolas Bonnefon #include <QMutexLocker>
22f35c72b9SNicolas Bonnefon #include <QFile>
23f35c72b9SNicolas Bonnefon 
24f35c72b9SNicolas Bonnefon #include "testlogfiltereddata.h"
25f35c72b9SNicolas Bonnefon #include "logdata.h"
2620ec540aSNicolas Bonnefon #include "logfiltereddata.h"
27f35c72b9SNicolas Bonnefon 
28f35c72b9SNicolas Bonnefon #if QT_VERSION < 0x040500
29f35c72b9SNicolas Bonnefon #define QBENCHMARK
30f35c72b9SNicolas Bonnefon #endif
31f35c72b9SNicolas Bonnefon 
32f35c72b9SNicolas Bonnefon #if !defined( TMPDIR )
33f35c72b9SNicolas Bonnefon #define TMPDIR "/tmp"
34f35c72b9SNicolas Bonnefon #endif
35f35c72b9SNicolas Bonnefon 
365f0a91faSNicolas Bonnefon static const qint64 ML_NB_LINES = 15000LL;
375fc7617dSNicolas Bonnefon static const char* ml_format="LOGDATA is a part of glogg, we are going to test it thoroughly, this is line\t\t%06d\n";
385fc7617dSNicolas Bonnefon static const int ML_VISIBLE_LINE_LENGTH = (76+8+4+6); // Without the final '\n' !
39f35c72b9SNicolas Bonnefon 
405f0a91faSNicolas Bonnefon static const qint64 SL_NB_LINES = 2000LL;
41f35c72b9SNicolas Bonnefon static const char* sl_format="LOGDATA is a part of glogg, we are going to test it thoroughly, this is line %06d\n";
42f35c72b9SNicolas Bonnefon 
437ab70cd2SNicolas Bonnefon static const char* partial_line_begin = "123... beginning of line.";
447ab70cd2SNicolas Bonnefon static const char* partial_line_end = " end of line 123.\n";
457ab70cd2SNicolas Bonnefon 
467ab70cd2SNicolas Bonnefon static const char* partial_nonmatching_line_begin = "Beginning of line.";
477ab70cd2SNicolas Bonnefon 
48f35c72b9SNicolas Bonnefon void TestLogFilteredData::initTestCase()
49f35c72b9SNicolas Bonnefon {
50f35c72b9SNicolas Bonnefon     QVERIFY( generateDataFiles() );
51f35c72b9SNicolas Bonnefon }
52f35c72b9SNicolas Bonnefon 
53f35c72b9SNicolas Bonnefon void TestLogFilteredData::simpleSearch()
54f35c72b9SNicolas Bonnefon {
55f35c72b9SNicolas Bonnefon     LogData logData;
56f35c72b9SNicolas Bonnefon 
57f35c72b9SNicolas Bonnefon     // First load the tests file
58f35c72b9SNicolas Bonnefon     // Register for notification file is loaded
593ab7c5b5SNicolas Bonnefon     connect( &logData, SIGNAL( loadingFinished( bool ) ),
60f35c72b9SNicolas Bonnefon             this, SLOT( loadingFinished() ) );
61f35c72b9SNicolas Bonnefon 
625f0a91faSNicolas Bonnefon     logData.attachFile( TMPDIR "/mediumlog.txt" );
63f35c72b9SNicolas Bonnefon     // Wait for the loading to be done
64f35c72b9SNicolas Bonnefon     {
65f35c72b9SNicolas Bonnefon         QApplication::exec();
66f35c72b9SNicolas Bonnefon     }
67f35c72b9SNicolas Bonnefon 
68f35c72b9SNicolas Bonnefon     QCOMPARE( logData.getNbLine(), ML_NB_LINES );
69f35c72b9SNicolas Bonnefon 
70f35c72b9SNicolas Bonnefon     // Now perform a simple search
71f35c72b9SNicolas Bonnefon     LogFilteredData* filteredData = logData.getNewFilteredData();
72f35c72b9SNicolas Bonnefon     connect( filteredData, SIGNAL( searchProgressed( int, int ) ),
73f35c72b9SNicolas Bonnefon             this, SLOT( searchProgressed( int, int ) ) );
74f35c72b9SNicolas Bonnefon 
75f35c72b9SNicolas Bonnefon     QSignalSpy progressSpy( filteredData, SIGNAL( searchProgressed( int, int ) ) );
76f35c72b9SNicolas Bonnefon 
775f0a91faSNicolas Bonnefon     qint64 matches[] = { 0, 15, 20, 135 };
780ed63e59SNicolas Bonnefon     QBENCHMARK {
79f35c72b9SNicolas Bonnefon         // Start the search
80f35c72b9SNicolas Bonnefon         filteredData->runSearch( QRegExp( "123" ) );
81f35c72b9SNicolas Bonnefon 
82f35c72b9SNicolas Bonnefon         // And check we receive data in 4 chunks (the first being empty)
83f35c72b9SNicolas Bonnefon         for ( int i = 0; i < 4; i++ ) {
84f35c72b9SNicolas Bonnefon             QApplication::exec();
85f35c72b9SNicolas Bonnefon             QCOMPARE( filteredData->getNbLine(), matches[i] );
86f35c72b9SNicolas Bonnefon         }
870ed63e59SNicolas Bonnefon     }
880ed63e59SNicolas Bonnefon 
890ed63e59SNicolas Bonnefon     QCOMPARE( progressSpy.count(), 4 );
90f35c72b9SNicolas Bonnefon 
91f35c72b9SNicolas Bonnefon     // Check the search
9246291021SNicolas Bonnefon     QCOMPARE( filteredData->isLineInMatchingList( 123 ), true );
9346291021SNicolas Bonnefon     QCOMPARE( filteredData->isLineInMatchingList( 124 ), false );
945fc7617dSNicolas Bonnefon     QCOMPARE( filteredData->getMaxLength(), ML_VISIBLE_LINE_LENGTH );
955fc7617dSNicolas Bonnefon     QCOMPARE( filteredData->getLineLength( 12 ), ML_VISIBLE_LINE_LENGTH );
965fc7617dSNicolas Bonnefon     QCOMPARE( filteredData->getNbLine(), 135LL );
97f35c72b9SNicolas Bonnefon     // Line beyond limit
98f35c72b9SNicolas Bonnefon     QCOMPARE( filteredData->isLineInMatchingList( 60000 ), false );
995f0a91faSNicolas Bonnefon     QCOMPARE( filteredData->getMatchingLineNumber( 0 ), 123LL );
100f35c72b9SNicolas Bonnefon 
1010ed63e59SNicolas Bonnefon     // Now let's try interrupting a search
1020ed63e59SNicolas Bonnefon     filteredData->runSearch( QRegExp( "123" ) );
1030ed63e59SNicolas Bonnefon     // ... wait for two chunks.
1040ed63e59SNicolas Bonnefon     QApplication::exec();
1050ed63e59SNicolas Bonnefon     QApplication::exec();
1060ed63e59SNicolas Bonnefon     // and interrupt!
1070ed63e59SNicolas Bonnefon     filteredData->interruptSearch();
1080ed63e59SNicolas Bonnefon     QCOMPARE( filteredData->getNbLine(), matches[1] );
1090ed63e59SNicolas Bonnefon     QApplication::exec();
1100ed63e59SNicolas Bonnefon     // After interrupt: should be 100% and the same number of matches
111d0d26f4fSNicolas Bonnefon     QCOMPARE( filteredData->getNbLine(), matches[2] );
1120ed63e59SNicolas Bonnefon 
1130ed63e59SNicolas Bonnefon     // (because there is no guarantee when the search is
1140ed63e59SNicolas Bonnefon     // interrupted, we are not sure how many chunk of result
1150ed63e59SNicolas Bonnefon     // we will get.)
1160ed63e59SNicolas Bonnefon 
117f35c72b9SNicolas Bonnefon     // Disconnect all signals
118f35c72b9SNicolas Bonnefon     disconnect( &logData, 0 );
119f35c72b9SNicolas Bonnefon 
120f35c72b9SNicolas Bonnefon     // Destroy the filtered data
121f35c72b9SNicolas Bonnefon     delete filteredData;
122f35c72b9SNicolas Bonnefon }
123f35c72b9SNicolas Bonnefon 
124f35c72b9SNicolas Bonnefon void TestLogFilteredData::multipleSearch()
125f35c72b9SNicolas Bonnefon {
126f35c72b9SNicolas Bonnefon     LogData logData;
127f35c72b9SNicolas Bonnefon 
128f35c72b9SNicolas Bonnefon     // First load the tests file
129f35c72b9SNicolas Bonnefon     // Register for notification file is loaded
1303ab7c5b5SNicolas Bonnefon     connect( &logData, SIGNAL( loadingFinished( bool ) ),
131f35c72b9SNicolas Bonnefon             this, SLOT( loadingFinished() ) );
132f35c72b9SNicolas Bonnefon 
1335f0a91faSNicolas Bonnefon     logData.attachFile( TMPDIR "/smalllog.txt" );
134f35c72b9SNicolas Bonnefon     // Wait for the loading to be done
135f35c72b9SNicolas Bonnefon     {
136f35c72b9SNicolas Bonnefon         QApplication::exec();
137f35c72b9SNicolas Bonnefon     }
138f35c72b9SNicolas Bonnefon 
139f35c72b9SNicolas Bonnefon     QCOMPARE( logData.getNbLine(), SL_NB_LINES );
140f35c72b9SNicolas Bonnefon 
1410ed63e59SNicolas Bonnefon     // Performs two searches in a row
142f35c72b9SNicolas Bonnefon     LogFilteredData* filteredData = logData.getNewFilteredData();
143f35c72b9SNicolas Bonnefon     connect( filteredData, SIGNAL( searchProgressed( int, int ) ),
144f35c72b9SNicolas Bonnefon             this, SLOT( searchProgressed( int, int ) ) );
145f35c72b9SNicolas Bonnefon 
1460ed63e59SNicolas Bonnefon     QSignalSpy progressSpy( filteredData,
1470ed63e59SNicolas Bonnefon             SIGNAL( searchProgressed( int, int ) ) );
148f35c72b9SNicolas Bonnefon 
149f35c72b9SNicolas Bonnefon     // Start the search, and immediately another one
1500ed63e59SNicolas Bonnefon     // (the second call should block until the first search is done)
151f35c72b9SNicolas Bonnefon     filteredData->runSearch( QRegExp( "1234" ) );
1520ed63e59SNicolas Bonnefon     filteredData->runSearch( QRegExp( "123" ) );
153f35c72b9SNicolas Bonnefon 
1540ed63e59SNicolas Bonnefon     for ( int i = 0; i < 3; i++ )
155f35c72b9SNicolas Bonnefon         QApplication::exec();
156f35c72b9SNicolas Bonnefon 
157f35c72b9SNicolas Bonnefon     // We should have the result for the 2nd search
1585f0a91faSNicolas Bonnefon     QCOMPARE( filteredData->getNbLine(), 12LL );
159f35c72b9SNicolas Bonnefon 
1600ed63e59SNicolas Bonnefon     QCOMPARE( progressSpy.count(), 4 );
1610ed63e59SNicolas Bonnefon 
1620ed63e59SNicolas Bonnefon     // Now a tricky one: we run a search and immediately attach a new file
1630ed63e59SNicolas Bonnefon     filteredData->runSearch( QRegExp( "123" ) );
1640ed63e59SNicolas Bonnefon     QApplication::exec();
1650ed63e59SNicolas Bonnefon     logData.attachFile( TMPDIR "/mediumlog.txt" );
1660ed63e59SNicolas Bonnefon 
1670ed63e59SNicolas Bonnefon     // We don't expect meaningful results but it should not crash!
16846291021SNicolas Bonnefon     for ( int i = 0; i < 2; i++ )
1690ed63e59SNicolas Bonnefon         QApplication::exec();
1700ed63e59SNicolas Bonnefon 
171f35c72b9SNicolas Bonnefon     // Disconnect all signals
172f35c72b9SNicolas Bonnefon     disconnect( &logData, 0 );
173f35c72b9SNicolas Bonnefon 
174f35c72b9SNicolas Bonnefon     // Destroy the filtered data
175f35c72b9SNicolas Bonnefon     delete filteredData;
176f35c72b9SNicolas Bonnefon }
177f35c72b9SNicolas Bonnefon 
178ba40a297SNicolas Bonnefon void TestLogFilteredData::updateSearch()
179ba40a297SNicolas Bonnefon {
180ba40a297SNicolas Bonnefon     LogData logData;
181ba40a297SNicolas Bonnefon 
182ba40a297SNicolas Bonnefon     // First load the tests file
183ba40a297SNicolas Bonnefon     // Register for notification file is loaded
184ba40a297SNicolas Bonnefon     connect( &logData, SIGNAL( loadingFinished( bool ) ),
185ba40a297SNicolas Bonnefon             this, SLOT( loadingFinished() ) );
186ba40a297SNicolas Bonnefon 
187ba40a297SNicolas Bonnefon     logData.attachFile( TMPDIR "/smalllog.txt" );
188ba40a297SNicolas Bonnefon     // Wait for the loading to be done
189ba40a297SNicolas Bonnefon     {
190ba40a297SNicolas Bonnefon         QApplication::exec();
191ba40a297SNicolas Bonnefon     }
192ba40a297SNicolas Bonnefon 
193ba40a297SNicolas Bonnefon     QCOMPARE( logData.getNbLine(), SL_NB_LINES );
194ba40a297SNicolas Bonnefon 
1955db60fd3SNicolas Bonnefon     // Perform a first search
196ba40a297SNicolas Bonnefon     LogFilteredData* filteredData = logData.getNewFilteredData();
197ba40a297SNicolas Bonnefon     connect( filteredData, SIGNAL( searchProgressed( int, int ) ),
198ba40a297SNicolas Bonnefon             this, SLOT( searchProgressed( int, int ) ) );
199ba40a297SNicolas Bonnefon 
200ba40a297SNicolas Bonnefon     QSignalSpy progressSpy( filteredData,
201ba40a297SNicolas Bonnefon             SIGNAL( searchProgressed( int, int ) ) );
202ba40a297SNicolas Bonnefon 
203ba40a297SNicolas Bonnefon     // Start a search
204ba40a297SNicolas Bonnefon     filteredData->runSearch( QRegExp( "123" ) );
205ba40a297SNicolas Bonnefon 
206ba40a297SNicolas Bonnefon     for ( int i = 0; i < 2; i++ )
207ba40a297SNicolas Bonnefon         QApplication::exec();
208ba40a297SNicolas Bonnefon 
209ba40a297SNicolas Bonnefon     // Check the result
210ba40a297SNicolas Bonnefon     QCOMPARE( filteredData->getNbLine(), 12LL );
211ba40a297SNicolas Bonnefon     QCOMPARE( progressSpy.count(), 2 );
212ba40a297SNicolas Bonnefon 
213*7d862d7eSNicolas Bonnefon     QWARN("Starting stage 2");
214*7d862d7eSNicolas Bonnefon 
215ba40a297SNicolas Bonnefon     // Add some data to the file
216ba40a297SNicolas Bonnefon     char newLine[90];
217ba40a297SNicolas Bonnefon     QFile file( TMPDIR "/smalllog.txt" );
218ba40a297SNicolas Bonnefon     if ( file.open( QIODevice::Append ) ) {
219ba40a297SNicolas Bonnefon         for (int i = 0; i < 3000; i++) {
220ba40a297SNicolas Bonnefon             snprintf(newLine, 89, sl_format, i);
221ba40a297SNicolas Bonnefon             file.write( newLine, qstrlen(newLine) );
222ba40a297SNicolas Bonnefon         }
2237ab70cd2SNicolas Bonnefon         // To test the edge case when the final line is not complete and matching
2247ab70cd2SNicolas Bonnefon         file.write( partial_line_begin, qstrlen( partial_line_begin ) );
225ba40a297SNicolas Bonnefon     }
226ba40a297SNicolas Bonnefon     file.close();
227ba40a297SNicolas Bonnefon 
2285db60fd3SNicolas Bonnefon     // Let the system do the update
2295db60fd3SNicolas Bonnefon     QApplication::exec();
2305db60fd3SNicolas Bonnefon 
231ba40a297SNicolas Bonnefon     // Start an update search
232ba40a297SNicolas Bonnefon     filteredData->updateSearch();
233ba40a297SNicolas Bonnefon 
2345db60fd3SNicolas Bonnefon     for ( int i = 0; i < 2; i++ )
235ba40a297SNicolas Bonnefon         QApplication::exec();
236ba40a297SNicolas Bonnefon 
237ba40a297SNicolas Bonnefon     // Check the result
2385db60fd3SNicolas Bonnefon     QCOMPARE( logData.getNbLine(), 5001LL );
2395db60fd3SNicolas Bonnefon     QCOMPARE( filteredData->getNbLine(), 26LL );
240ba40a297SNicolas Bonnefon     QCOMPARE( progressSpy.count(), 4 );
2417ab70cd2SNicolas Bonnefon 
242*7d862d7eSNicolas Bonnefon     QWARN("Starting stage 3");
243*7d862d7eSNicolas Bonnefon 
2447ab70cd2SNicolas Bonnefon     // Add a couple more lines, including the end of the unfinished one.
2457ab70cd2SNicolas Bonnefon     if ( file.open( QIODevice::Append ) ) {
2467ab70cd2SNicolas Bonnefon         file.write( partial_line_end, qstrlen( partial_line_end ) );
2477ab70cd2SNicolas Bonnefon         for (int i = 0; i < 20; i++) {
2487ab70cd2SNicolas Bonnefon             snprintf(newLine, 89, sl_format, i);
2497ab70cd2SNicolas Bonnefon             file.write( newLine, qstrlen(newLine) );
2507ab70cd2SNicolas Bonnefon         }
2517ab70cd2SNicolas Bonnefon         // To test the edge case when the final line is not complete and not matching
2527ab70cd2SNicolas Bonnefon         file.write( partial_nonmatching_line_begin,
2537ab70cd2SNicolas Bonnefon                 qstrlen( partial_nonmatching_line_begin ) );
2547ab70cd2SNicolas Bonnefon     }
2557ab70cd2SNicolas Bonnefon     file.close();
2567ab70cd2SNicolas Bonnefon 
2577ab70cd2SNicolas Bonnefon     // Start an update search
2587ab70cd2SNicolas Bonnefon     filteredData->updateSearch();
2597ab70cd2SNicolas Bonnefon 
2607ab70cd2SNicolas Bonnefon     for ( int i = 0; i < 3; i++ )
2617ab70cd2SNicolas Bonnefon         QApplication::exec();
2627ab70cd2SNicolas Bonnefon 
2637ab70cd2SNicolas Bonnefon     // Check the result
2647ab70cd2SNicolas Bonnefon     QCOMPARE( logData.getNbLine(), 5022LL );
2657ab70cd2SNicolas Bonnefon     QCOMPARE( filteredData->getNbLine(), 26LL );
2667ab70cd2SNicolas Bonnefon     QCOMPARE( progressSpy.count(), 6 );
2677ab70cd2SNicolas Bonnefon 
268*7d862d7eSNicolas Bonnefon     QWARN("Starting stage 4");
269*7d862d7eSNicolas Bonnefon 
2707ab70cd2SNicolas Bonnefon     // Now test the case where a match is found at the end of an updated line.
2717ab70cd2SNicolas Bonnefon     if ( file.open( QIODevice::Append ) ) {
2727ab70cd2SNicolas Bonnefon         file.write( partial_line_end, qstrlen( partial_line_end ) );
2737ab70cd2SNicolas Bonnefon         for (int i = 0; i < 20; i++) {
2747ab70cd2SNicolas Bonnefon             snprintf(newLine, 89, sl_format, i);
2757ab70cd2SNicolas Bonnefon             file.write( newLine, qstrlen(newLine) );
2767ab70cd2SNicolas Bonnefon         }
2777ab70cd2SNicolas Bonnefon     }
2787ab70cd2SNicolas Bonnefon     file.close();
2797ab70cd2SNicolas Bonnefon 
2807ab70cd2SNicolas Bonnefon     // Start an update search
2817ab70cd2SNicolas Bonnefon     filteredData->updateSearch();
2827ab70cd2SNicolas Bonnefon 
2837ab70cd2SNicolas Bonnefon     for ( int i = 0; i < 3; i++ )
2847ab70cd2SNicolas Bonnefon         QApplication::exec();
2857ab70cd2SNicolas Bonnefon 
2867ab70cd2SNicolas Bonnefon     // Check the result
2877ab70cd2SNicolas Bonnefon     QCOMPARE( logData.getNbLine(), 5042LL );
2887ab70cd2SNicolas Bonnefon     QCOMPARE( filteredData->getNbLine(), 27LL );
2897ab70cd2SNicolas Bonnefon     QCOMPARE( progressSpy.count(), 8 );
290ba40a297SNicolas Bonnefon }
291ba40a297SNicolas Bonnefon 
292f35c72b9SNicolas Bonnefon //
293f35c72b9SNicolas Bonnefon // Private functions
294f35c72b9SNicolas Bonnefon //
295f35c72b9SNicolas Bonnefon void TestLogFilteredData::loadingFinished()
296f35c72b9SNicolas Bonnefon {
297f35c72b9SNicolas Bonnefon     QApplication::quit();
298f35c72b9SNicolas Bonnefon }
299f35c72b9SNicolas Bonnefon 
300f35c72b9SNicolas Bonnefon void TestLogFilteredData::searchProgressed( int nbMatches, int completion )
301f35c72b9SNicolas Bonnefon {
302f35c72b9SNicolas Bonnefon     QApplication::quit();
303f35c72b9SNicolas Bonnefon }
304f35c72b9SNicolas Bonnefon 
305f35c72b9SNicolas Bonnefon bool TestLogFilteredData::generateDataFiles()
306f35c72b9SNicolas Bonnefon {
307f35c72b9SNicolas Bonnefon     char newLine[90];
308f35c72b9SNicolas Bonnefon 
309f35c72b9SNicolas Bonnefon     QFile file( TMPDIR "/mediumlog.txt" );
310f35c72b9SNicolas Bonnefon     if ( file.open( QIODevice::WriteOnly ) ) {
311f35c72b9SNicolas Bonnefon         for (int i = 0; i < ML_NB_LINES; i++) {
312f35c72b9SNicolas Bonnefon             snprintf(newLine, 89, ml_format, i);
313f35c72b9SNicolas Bonnefon             file.write( newLine, qstrlen(newLine) );
314f35c72b9SNicolas Bonnefon         }
315f35c72b9SNicolas Bonnefon     }
316f35c72b9SNicolas Bonnefon     else {
317f35c72b9SNicolas Bonnefon         return false;
318f35c72b9SNicolas Bonnefon     }
319f35c72b9SNicolas Bonnefon     file.close();
320f35c72b9SNicolas Bonnefon 
321f35c72b9SNicolas Bonnefon     file.setFileName( TMPDIR "/smalllog.txt" );
322f35c72b9SNicolas Bonnefon     if ( file.open( QIODevice::WriteOnly ) ) {
323f35c72b9SNicolas Bonnefon         for (int i = 0; i < SL_NB_LINES; i++) {
324f35c72b9SNicolas Bonnefon             snprintf(newLine, 89, sl_format, i);
325f35c72b9SNicolas Bonnefon             file.write( newLine, qstrlen(newLine) );
326f35c72b9SNicolas Bonnefon         }
327f35c72b9SNicolas Bonnefon     }
328f35c72b9SNicolas Bonnefon     else {
329f35c72b9SNicolas Bonnefon         return false;
330f35c72b9SNicolas Bonnefon     }
331f35c72b9SNicolas Bonnefon     file.close();
332f35c72b9SNicolas Bonnefon 
333f35c72b9SNicolas Bonnefon     return true;
334f35c72b9SNicolas Bonnefon }
335