109 lines
2.2 KiB
C++
109 lines
2.2 KiB
C++
#include <iostream>
|
|
#include <fstream>
|
|
#include <sstream>
|
|
#include <string>
|
|
#include "SharedLib.h"
|
|
#include "FileReaderUtils.h"
|
|
|
|
// --- Enum for the parser's state ---
|
|
enum class EParseState
|
|
{
|
|
NONE,
|
|
NODES,
|
|
EDGES
|
|
};
|
|
|
|
void readGraphFromFile(const std::string& aFilename, FNodeRead aOnNodeRead, FEdgeRead aOnEdgeRead)
|
|
{
|
|
if (aFilename.empty()) return;
|
|
|
|
std::ifstream file(aFilename);
|
|
if (!file.is_open())
|
|
{
|
|
// Optional: print an error
|
|
// std::cerr << "Error: Could not open file " << aFilename << std::endl;
|
|
return;
|
|
}
|
|
|
|
std::string line;
|
|
EParseState currentState = EParseState::NONE;
|
|
int totalCount = 0;
|
|
int currentIndex = 0;
|
|
bool keepReading = true;
|
|
|
|
while (keepReading && std::getline(file, line))
|
|
{
|
|
if (line.empty()) continue;
|
|
|
|
if (line[0] == '[')
|
|
{
|
|
// --- 2. USE THE SHARED FUNCTION ---
|
|
totalCount = GetRecordCount(line);
|
|
currentIndex = 0;
|
|
|
|
if (line.find("[NODES") != std::string::npos)
|
|
{
|
|
currentState = EParseState::NODES;
|
|
continue;
|
|
}
|
|
else if (line.find("[EDGES") != std::string::npos)
|
|
{
|
|
currentState = EParseState::EDGES;
|
|
continue;
|
|
}
|
|
// If it's a comment or other header, reset state and count
|
|
currentState = EParseState::NONE;
|
|
totalCount = 0;
|
|
continue;
|
|
}
|
|
|
|
// Process data based on the current state
|
|
switch (currentState)
|
|
{
|
|
case EParseState::NODES:
|
|
if (aOnNodeRead)
|
|
{
|
|
if (!aOnNodeRead(currentIndex, totalCount, line))
|
|
{
|
|
keepReading = false;
|
|
}
|
|
currentIndex++;
|
|
}
|
|
break;
|
|
|
|
case EParseState::EDGES:
|
|
{
|
|
std::istringstream edgeStream(line);
|
|
std::string fromNode, toNode, weightStr;
|
|
|
|
if (std::getline(edgeStream, fromNode, ';') &&
|
|
std::getline(edgeStream, toNode, ';') &&
|
|
std::getline(edgeStream, weightStr))
|
|
{
|
|
try
|
|
{
|
|
// Use std::stof (string to float) for weight
|
|
float weight = std::stof(weightStr);
|
|
if (aOnEdgeRead)
|
|
{
|
|
if (!aOnEdgeRead(currentIndex, totalCount, fromNode, toNode, weight))
|
|
{
|
|
keepReading = false;
|
|
}
|
|
currentIndex++;
|
|
}
|
|
}
|
|
catch (const std::exception&)
|
|
{
|
|
// Failed to parse float, skip this line
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case EParseState::NONE:
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
file.close();
|
|
} |