Skip to content

Commit

Permalink
Implement local algorithm to parse a new line terminated line from a …
Browse files Browse the repository at this point in the history
…file
  • Loading branch information
imikejackson committed May 21, 2017
1 parent b78a4eb commit e5cf53b
Show file tree
Hide file tree
Showing 2 changed files with 126 additions and 16 deletions.
126 changes: 111 additions & 15 deletions Source/SVWidgetsLib/Widgets/ImportASCIIDataWizard/LineCounterObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,20 @@

#include "LineCounterObject.h"

#include <assert.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>

#include <fstream>
#include <iostream>
#include <istream>
#include <fstream>
#include <string>

#include <QtCore/QTextStream>
#include <QtCore/QFile>
#include <QtCore/QDebug>
#include <QtCore/QFile>
#include <QtCore/QTextStream>

#include "SIMPLib/SIMPLibTypes.h"

Expand Down Expand Up @@ -88,13 +95,13 @@ void LineCounterObject::run()
QFile qFile(m_FilePath);
int64_t fileSize = qFile.size();

// auto start = std::chrono::system_clock::now();
// auto start = std::chrono::system_clock::now();

m_NumOfLines = 0;

FILE* fp = nullptr;
char* line = nullptr;
size_t len = 0;
std::vector<char> line;
size_t length = 0;
int64_t read = 0;

fp = fopen(m_FilePath.toStdString().c_str(), "r");
Expand All @@ -111,7 +118,7 @@ void LineCounterObject::run()
int64_t progIncrement = fileSize / 1000;
int64_t currentThresh = progIncrement;

while((read = getline(&line, &len, fp)) != -1)
while((read = parseLine(line, length, fp, '\n')) != -1)
{
currentByte += read;
m_NumOfLines++;
Expand All @@ -125,15 +132,11 @@ void LineCounterObject::run()
}

fclose(fp);
if(line) {
free(line);
}

// std::cout << "Number of Lines: " << m_NumOfLines << std::endl;
// auto end = std::chrono::system_clock::now();
// std::cout << "Number of Lines: " << m_NumOfLines << std::endl;
// auto end = std::chrono::system_clock::now();

// std::chrono::duration<double> diff = end - start;
// std::cout << "Millis to Read: " << diff.count() << std::endl;
// std::chrono::duration<double> diff = end - start;
// std::cout << "Millis to Read: " << diff.count() << std::endl;

emit finished();
}
Expand All @@ -145,3 +148,96 @@ int LineCounterObject::getNumberOfLines()
{
return m_NumOfLines;
}

// -----------------------------------------------------------------------------
//
// -----------------------------------------------------------------------------
int LineCounterObject::parseLine(std::vector<char> &line, size_t &n, FILE* stream, char terminator)
{
static const int k_MinChunk = 64;
int ncharsAvailable;
char* readPos;
int ret;

if(nullptr == stream)
{
errno = EINVAL;
return -1;
}

if(line.size() == 0)
{
n = k_MinChunk;
line.resize(n);
}

ncharsAvailable = n;
readPos = line.data();

for(;;)
{
int save_errno;
int c = getc(stream);

save_errno = errno;

/* We always want at least one char left in the buffer, since we
always (unless we get an error while reading the first char)
NUL-terminate the line buffer. */

assert((line.data() + n) == (readPos + ncharsAvailable));
if(ncharsAvailable < 2)
{
if(n > k_MinChunk)
{
n *= 2;
}
else {
n += k_MinChunk;
}
ncharsAvailable = n + line.data() - readPos;
line.resize(n);
if(line.size())
{
errno = ENOMEM;
return -1;
}
readPos = n - ncharsAvailable + line.data();
assert((line.data() + n) == (readPos + ncharsAvailable));
}

if(ferror(stream))
{
/* Might like to return partial line, but there is no
place for us to store errno. And we don't want to just
lose errno. */
errno = save_errno;
return -1;
}

if(c == EOF)
{
/* Return partial line, if any. */
if(readPos == line.data())
{
return -1;
} else {
break;
}
}

*readPos++ = c;
ncharsAvailable--;

if(c == terminator)
{
break;
}
}

/* Done - NUL terminate and return the number of chars read. */
*readPos = '\0';

ret = readPos - (line.data());
return ret;
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@
#ifndef _linecounterobject_h_
#define _linecounterobject_h_

#include <stdio.h>

#include <vector>

#include <QtCore/QObject>

class LineCounterObject : public QObject
Expand Down Expand Up @@ -72,9 +76,19 @@ class LineCounterObject : public QObject

private:
QString m_FilePath;

int m_NumOfLines;

/**
* @brief parseLine
* @param line buffer of char to read into
* @param n
* @param stream A FILE* pointer
* @param terminator How to chop the lines up
* @param offset
* @return Return the number of characters read (not including the null terminator), or -1 on error or EOF.
*/
int parseLine(std::vector<char> &line, size_t &n, FILE* stream, char terminator);

LineCounterObject(const LineCounterObject&); // Copy Constructor Not Implemented
void operator=(const LineCounterObject&); // Operator '=' Not Implemented
};
Expand Down

0 comments on commit e5cf53b

Please sign in to comment.