/*
* Copyright ©2026 Soham Pardeshi. All rights reserved.
* Permission is hereby granted to students registered for University of
* Washington CSE 333 for use solely during Summer Quarter 2026 for
* purposes of the course. No other use, copying, distribution, or
* modification is permitted without prior written consent. Copyrights
* for third-party components of this work must be honored. Instructors
* interested in reusing these course materials should contact the author.
*/
#include <string.h>
#include <algorithm>
#include <unistd.h>
#include <sstream>
#include "./SocketLineReader.h"
bool SocketLineReader::GetNextLine(std::string *line) {
// Keep attempting to read data until we find a '\n' terminated
// line within buf_.
while (1) {
// Do we have a '\n' terminated line in buf_? If so, return it
// and shift the data in buf_.
unsigned int offset = 0;
while (offset < buf_.size()) {
if (buf_[offset] == '\n') {
// Found our line! Return it and shift buf_ down.
*line = std::string(&(buf_[0]), offset + 1);
buf_.erase(buf_.begin(), buf_.begin() + offset + 1);
return true;
}
offset++;
}
// We didn't find a line, so we need to read() more data. First,
// we need to resize buf_ to handle the new characters we might
// read; later, we'll trim the characters we didn't.
unsigned int readoffset = buf_.size();
buf_.resize(readoffset + kReadAmount);
// Read more data.
int res = read(cfd_, &(buf_[readoffset]), kReadAmount);
if (res > 0) {
// Trim the part of the buffer we didn't read into.
buf_.erase(buf_.begin() + readoffset + res,
buf_.begin() + readoffset + kReadAmount);
continue;
}
// Did we hit EINTR/EAGAIN?
if ((res == -1) && ((errno == EAGAIN) || (errno == EINTR)))
continue;
// We either hit EOF (res == 0) or a real error (res == -1)
break;
}
// Broke out of the loop, so we must have hit an error.
return false;
}
std::vector<std::string> SocketLineReader::SplitIntoWords(
const std::string &line) {
std::stringstream ss(line);
std::vector<std::string> retvec;
std::string word;
while (ss >> word) {
std::transform(word.begin(), word.end(), word.begin(), ::tolower);
retvec.push_back(word);
}
return retvec;
}