diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json new file mode 100644 index 0000000..1211532 --- /dev/null +++ b/.vscode/c_cpp_properties.json @@ -0,0 +1,17 @@ +{ + "configurations": [ + { + "name": "Linux", + "includePath": [ + "${workspaceFolder}/**" + ], + "defines": [], + "compilerPath": "/usr/bin/gcc", + "cStandard": "gnu17", + "cppStandard": "gnu++14", + "intelliSenseMode": "linux-gcc-x64", + "configurationProvider": "ms-vscode.cmake-tools" + } + ], + "version": 4 +} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json index 82cfcc9..76c6c39 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -1,3 +1,5 @@ { - "cmake.configureOnOpen": false + "cmake.configureOnOpen": false, + "C_Cpp.default.configurationProvider": "ms-vscode.cmake-tools", + "C_Cpp.errorSquiggles": "Enabled" } \ No newline at end of file diff --git a/Directory.h b/Directory.h index 56f203b..57795ba 100644 --- a/Directory.h +++ b/Directory.h @@ -3,6 +3,7 @@ # include "includes" # include "DirectoryEntry.h" +# include "Log.h" namespace coreutils { @@ -29,7 +30,7 @@ namespace coreutils { } DirectoryEntry get() { - if(cursor == directory.end()) + if(eod()) return NULL; return cursor->second; } @@ -42,7 +43,7 @@ namespace coreutils { DIR *dir; std::map directory; std::map::iterator cursor; - + }; } diff --git a/DirectoryEntry.h b/DirectoryEntry.h index 1b6bd68..09fe9c9 100644 --- a/DirectoryEntry.h +++ b/DirectoryEntry.h @@ -17,6 +17,18 @@ namespace coreutils { std::string getName() { return std::string(entry.d_name); } + + unsigned char getType() { + return entry.d_type; + } + + bool isFile() { + return entry.d_type == DT_REG; + } + + bool isDirectory() { + return entry.d_type == DT_DIR; + } private: struct dirent entry; diff --git a/Exception.h b/Exception.h index 66d5b37..ac803de 100644 --- a/Exception.h +++ b/Exception.h @@ -1,21 +1,22 @@ #ifndef __Exception_h__ #define __Exception_h__ -#include "includes" +#include +#include namespace coreutils { - + class Exception { - + public: Exception(std::string text, std::string file = __FILE__, int line = __LINE__, int errorNumber = -1); - + std::string className; std::string file; int line; std::string text; int errorNumber; - + }; } diff --git a/File.cpp b/File.cpp index 722ada1..b0605e7 100644 --- a/File.cpp +++ b/File.cpp @@ -23,7 +23,8 @@ namespace coreutils { } File::~File() { - + close(fd); + setBufferSize(0); } void File::setBufferSize(size_t size) { diff --git a/File.h b/File.h index 393f3d7..578028f 100644 --- a/File.h +++ b/File.h @@ -5,32 +5,32 @@ /// /// File -/// +/// /// File abstraction class for accessing local file system files. /// namespace coreutils { - + class File { - + public: File(std::string fileName, int mode = O_RDONLY, int authority = 0664); - ~File(); + ~File(); void setBufferSize(size_t size); void read(); void write(std::string data); std::string asString(); - + char *buffer; size_t size; - + std::string fileName; - + private: int fd; - + }; - + } #endif diff --git a/IMFBody.h b/IMFBody.h deleted file mode 100644 index 4c2961c..0000000 --- a/IMFBody.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef __IMFBody_h__ -#define __IMFBody_h__ - -#include "ZString.h" - -namespace coreutils { - - class IMFBody : public ZString { - - public: - IMFBody() {} - IMFBody(ZString &body) : ZString(body) {} - - }; - -} - -#endif diff --git a/IMFFormData.cpp b/IMFFormData.cpp index 93b1b5c..1b36b42 100644 --- a/IMFFormData.cpp +++ b/IMFFormData.cpp @@ -3,21 +3,19 @@ #include "IMFPlainText.h" namespace coreutils { - + IMFFormData::IMFFormData() {} - IMFFormData::IMFFormData(ZString &in, ZString boundary) : IMFMultipart(in, boundary) { - - } - - IMFBody * IMFFormData::getByName(ZString name) { + IMFFormData::IMFFormData(ZString &in, ZString &boundary) : IMFMultipart(in, boundary) {} + + ZString IMFFormData::getByName(ZString &name) { for(ZString section: sections) { IMFMessage message(section); - if(message.getHeaderKeyPairValue((char *)"Content-Disposition", (char *)"name").equals(name)) { - return message.getBody(); - } + if(message.getHeaderKeyPairValue("Content-Disposition", ("name")).equals(name)) { + return message.multipart; + } } - return new IMFBody(); + return ZString(); } - + } diff --git a/IMFFormData.h b/IMFFormData.h index d0d4325..3a73f59 100644 --- a/IMFFormData.h +++ b/IMFFormData.h @@ -4,17 +4,17 @@ # include "IMFMultipart.h" namespace coreutils { - + class IMFFormData: public IMFMultipart { - + public: IMFFormData(); - IMFFormData(ZString &in, ZString boundary); - - IMFBody * getByName(ZString name); - + IMFFormData(ZString &in, ZString &boundary); + + ZString getByName(ZString &name); + }; - + } #endif diff --git a/IMFHeader.cpp b/IMFHeader.cpp index 1205df1..467ab3c 100644 --- a/IMFHeader.cpp +++ b/IMFHeader.cpp @@ -4,29 +4,19 @@ namespace coreutils { - IMFHeader::IMFHeader() : ZString() { - - } - IMFHeader::IMFHeader(ZString &in) : ZString(in) { - key = in.getTokenInclude((char *)"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-0123456789"); + key = in.getTokenInclude("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz-_0123456789"); if(key.getLength() != 0) { - if(!in.ifNext((char *)":")) { - printf("key=%s %02X\n", key.str().c_str(), in.str()[0]); - throw coreutils::Exception("Invalid character in expected header token."); - } + if(!in.ifNext(":")) + throw coreutils::Exception("Invalid character in expected header token."); in.skipWhitespace(); value = in.goeol(); } else if(in.skipWhitespace() > 0) {} else if(in.str() == "") {} - coreutils::Log(coreutils::LOG_DEBUG_2) << " " << key << "[" << value << "]"; } - IMFHeader::IMFHeader(ZString key, ZString value) : ZString() { - this->key = key; - this->value = value; - } + IMFHeader::IMFHeader(ZString key, ZString value) : ZString(), key(key), value(value) {} ZString IMFHeader::getKey() { return key; diff --git a/IMFHeader.h b/IMFHeader.h index 29c8ebe..9b8bc38 100644 --- a/IMFHeader.h +++ b/IMFHeader.h @@ -2,13 +2,13 @@ #define __IMFHeader_h__ #include "ZString.h" +#include namespace coreutils { class IMFHeader : public ZString { public: - IMFHeader(); IMFHeader(ZString &in); IMFHeader(ZString key, ZString value); diff --git a/IMFMessage.cpp b/IMFMessage.cpp index 8a3c3c8..3d471dd 100644 --- a/IMFMessage.cpp +++ b/IMFMessage.cpp @@ -6,41 +6,48 @@ namespace coreutils { - IMFMessage::IMFMessage() : ZString() { - } + IMFMessage::IMFMessage() : ZString() {} IMFMessage::IMFMessage(ZString &in) : ZString(in) { - while (!in.ifNext("\r\n")) { - headers.emplace_back(in); - } + while (!in.ifNext("\r\n")) + headers.emplace_back(in); ZString type = getHeader("Content-Type"); + int len = getHeader("Content-Length").asInteger(); if(len > 0) { - ZString block = in.readBlock(len); - if(type.equals("multipart/form-data")) - body = new IMFMultipart(block, getHeaderKeyPairValue("Content-Type", "boundary")); - else if(type.equals("text/plain")) - body = new IMFPlainText(block); - else - body = new IMFBody(block); + block = in.readBlock(len); + if(type.equals("multipart/form-data")) { + ZString boundary(getHeaderKeyPairValue("Content-Type", "boundary")); + multipart = IMFMultipart(block, boundary); + } } } + IMFMessage::~IMFMessage() {} + void IMFMessage::output(std::stringstream &out) { - for(IMFHeader header: headers) { - out << header.getKey() << ": " << header.getValue() << "\r\n"; - } - out << "\r\n"; +// for(IMFHeader header: headers) { +// out << header.getKey() << ": " << header.getValue() << "\r\n"; +// } + out << newHeaders.str() << "\r\n"; } - void IMFMessage::addHeader(ZString key, ZString value) { - headers.emplace_back(key, value); + void IMFMessage::addHeader(const char *key, const char *value) { + newHeaders << key << ": " << value << "\r\n"; } - void IMFMessage::addHeader(const char *key, ZString value) { - headers.emplace_back(ZString(key), value); + void IMFMessage::addHeader(const char *key, std::string &value) { + newHeaders << key << ": " << value << "\r\n"; + } + + void IMFMessage::addHeader(ZString &key, ZString &value) { + newHeaders << key << ": " << value << "\r\n"; + } + + void IMFMessage::addHeader(const char *key, ZString &value) { + newHeaders << key << ": " << value << "\r\n"; } ZString IMFMessage::getHeader(ZString key, bool valueOnly) { @@ -51,7 +58,7 @@ namespace coreutils { std::vector split = ZString(value).split(";"); value = split[0]; } - return value; + return value; } } return ZString(); @@ -64,37 +71,27 @@ namespace coreutils { ZString IMFMessage::getHeaderKeyPairValue(ZString headerKey, ZString key) { ZString value; ZString psource(getHeader(headerKey, false)); - std::vector sourcep = psource.split(";"); - for(ZString work: sourcep) { + for(ZString work: psource.split(";")) { work.skipWhitespace(); ZString token = work.getTokenExclude("="); - if(work.ifNext((char *)"=")) { + if(work.ifNext("=")) { if(token.equals(key)) { - if(work.ifNext((char *)"\"")) { - value = work.getTokenExclude((char *)"\""); - return value; - } - else { - value = work; - return value; - } + if(work.ifNext("\"")) + value = work.getTokenExclude("\""); + else + value = work; + return value; } else continue; - - } else if (work.ifNext((char *)";") || work.ifNext((char *)" ")) { + } else if (work.ifNext(";") || work.ifNext(" ")) { if(token.equals(key)) - return ZString((char *)"true"); + return ZString("true"); else continue; - } } - return ZString((char *)"false"); - } - - IMFBody * IMFMessage::getBody() { - return body; + return ZString(); } } diff --git a/IMFMessage.h b/IMFMessage.h index 793d8f3..aa06ec3 100644 --- a/IMFMessage.h +++ b/IMFMessage.h @@ -1,9 +1,12 @@ #ifndef __IMFMessage_h__ #define __IMFMessage_h__ +#include +#include +#include #include "ZString.h" +#include "IMFMultipart.h" #include "IMFHeader.h" -#include "IMFBody.h" namespace coreutils { @@ -12,22 +15,26 @@ namespace coreutils { public: IMFMessage(); IMFMessage(ZString &in); + virtual ~IMFMessage(); void output(std::stringstream &out); - void addHeader(ZString key, ZString value); - void addHeader(const char *key, ZString value); + void addHeader(const char *key, std::string &value); + void addHeader(const char *key, const char *value); + void addHeader(ZString &key, ZString &value); + void addHeader(const char *key, ZString &value); ZString getHeader(ZString key, bool valueOnly = true); ZString getHeaderKeyPairValue(const char *headerKey, const char *key); ZString getHeaderKeyPairValue(ZString headerKey, ZString key); - IMFBody * getBody(); + IMFMultipart multipart; + ZString block; + char contentLength[8]; protected: std::vector headers; - - IMFBody *body; + std::stringstream newHeaders; }; diff --git a/IMFMultipart.cpp b/IMFMultipart.cpp index fd5e8fa..a64e64e 100644 --- a/IMFMultipart.cpp +++ b/IMFMultipart.cpp @@ -1,30 +1,35 @@ #include "IMFMultipart.h" +#include "Log.h" namespace coreutils { - + IMFMultipart::IMFMultipart() {} - - IMFMultipart::IMFMultipart(ZString &in, ZString boundary) { + + IMFMultipart::IMFMultipart(ZString &in, ZString &boundary) { + Log(LOG_DEBUG_1) << in; std::stringstream temp; - temp << "\r\n--" << boundary; - sections = in.split((char *)temp.str().c_str()); + temp << "--" << boundary; + sections = in.split(temp.str().c_str()); for(int ix = 0; ix < sections.size(); ++ix) { - if(sections[ix].equals((char *)"--\r\n")) - sections[ix] = ZString((char *)""); - sections[ix].ifNext((char *)"\r\n"); + sections[ix].ifNext("\r\n"); + sections[ix].ifCRLF(); + Log(LOG_DEBUG_1) << "[" << sections[ix] << "]."; + if(sections[ix].equals("--")) + sections[ix] = ZString(""); + sections[ix].ifNext("\r\n"); } } - + std::string IMFMultipart::toString() { return std::string(getData(), getLength()); } - + int IMFMultipart::getCount() { return sections.size(); } - + ZString IMFMultipart::getSectionAt(int index) { return sections[index]; } - + } diff --git a/IMFMultipart.h b/IMFMultipart.h index 2536bdf..e8d4a59 100644 --- a/IMFMultipart.h +++ b/IMFMultipart.h @@ -2,15 +2,14 @@ #define __IMFMultipart_h__ #include "ZString.h" -#include "IMFBody.h" namespace coreutils { - class IMFMultipart: public IMFBody { + class IMFMultipart: public ZString { public: IMFMultipart(); - IMFMultipart(ZString &in, ZString boundary); + IMFMultipart(ZString &in, ZString &boundary); std::string toString(); int getCount(); diff --git a/IMFPlainText.cpp b/IMFPlainText.cpp index f1f18a6..ef445b2 100644 --- a/IMFPlainText.cpp +++ b/IMFPlainText.cpp @@ -1,11 +1,10 @@ #include "IMFPlainText.h" namespace coreutils { - + IMFPlainText::IMFPlainText() { } - - IMFPlainText::IMFPlainText(ZString &in) : IMFBody() { - } - + + IMFPlainText::IMFPlainText(ZString &in) : ZString(in.str().c_str()) {} + } diff --git a/IMFPlainText.h b/IMFPlainText.h index 1cf2b5a..886f815 100644 --- a/IMFPlainText.h +++ b/IMFPlainText.h @@ -2,11 +2,10 @@ #define __IMFPlainText_h__ #include "ZString.h" -#include "IMFBody.h" namespace coreutils { - class IMFPlainText: public IMFBody { + class IMFPlainText: public ZString { public: IMFPlainText(); diff --git a/IMFRequest.cpp b/IMFRequest.cpp index 3b73661..5bf4ad2 100644 --- a/IMFRequest.cpp +++ b/IMFRequest.cpp @@ -5,8 +5,8 @@ namespace coreutils { IMFRequest::IMFRequest(ZString &in) : ZString(in) { - in.goeol(); - this->split(" ", 3); + setZString(in.goeol()); + split(" "); } ZString IMFRequest::getMethod() { diff --git a/IMFRequest.h b/IMFRequest.h index c64c548..9128d56 100644 --- a/IMFRequest.h +++ b/IMFRequest.h @@ -14,7 +14,7 @@ namespace coreutils { ZString getMethod(); ZString getURI(); ZString getProtocol(); - + }; } diff --git a/IMFResponse.cpp b/IMFResponse.cpp index 6430fe6..b82305c 100644 --- a/IMFResponse.cpp +++ b/IMFResponse.cpp @@ -15,16 +15,18 @@ namespace coreutils { std::stringstream response; response << protocol << " " << code << " " << text << CRLF; - if(mode == LENGTH) - addHeader((char *)"Content-Length", (char *)std::to_string(content.gcount()).c_str()); + if(mode == LENGTH) { + sprintf(contentLength, "%li", content.str().length()); + ZString conlen(contentLength); + addHeader("Content-Length", conlen); + } else - addHeader((char *)"Transfer-Encoding", (char *)"chunked"); + addHeader("Transfer-Encoding", "chunked"); - addHeader((char *)"Server", (char *)"JETServer v0.0.1"); + addHeader("Server", "JETServer v0.0.1"); output(response); response << content.str(); -// core::Log(core::LOG_DEBUG_4) << response.str(); return response; } @@ -40,12 +42,4 @@ namespace coreutils { this->text = text; } - void IMFResponse::setCookie(ZString key, ZString data) { - addHeader("Set-Cookie", data); - } - - void IMFResponse::setCookie(ZString key, std::string data) { - addHeader("Set-Cookie", ZString(data.c_str())); - } - } diff --git a/IMFResponse.h b/IMFResponse.h index c5f0b0e..8f3507b 100644 --- a/IMFResponse.h +++ b/IMFResponse.h @@ -81,9 +81,6 @@ namespace coreutils { void setText(ZString text); - void setCookie(ZString key, ZString data); - void setCookie(ZString key, std::string data); - private: ZString protocol; ZString code; diff --git a/ZString.cpp b/ZString.cpp index 2354c11..6366579 100644 --- a/ZString.cpp +++ b/ZString.cpp @@ -4,8 +4,8 @@ namespace coreutils { std::ostream& operator<<(std::ostream& os, const ZString &zstring) { - for(int ix = 0; ix < zstring.length; ++ix) { - os << zstring.data[ix]; + for(int ix = 0; ix < (zstring.length - (zstring.cursor - zstring.data)); ++ix) { + os << zstring.cursor[ix]; } return os; } @@ -39,6 +39,24 @@ namespace coreutils { // Log(LOG_DEBUG_2) << "ZString Copy Constructor: "; } + ZString::ZString(std::string data) { + this->data = (char *)data.c_str(); + length = data.length(); + cursor = (char *)data.c_str(); + } + + bool ZString::operator<(const ZString &valuex) const { + return (strncmp(cursor, valuex.cursor, (valuex.length <= length ? valuex.length: length) < 0)); + } + + bool ZString::operator>(const ZString &valuex) const { + return (strncmp(data, valuex.data, valuex.length <= length ? valuex.length: length) > 0); + } + + bool ZString::operator==(const ZString &valuex) const { + return (strncmp(data, valuex.data, valuex.length <= length ? valuex.length: length) == 0); + } + std::vector &ZString::getList() { return list; } @@ -49,130 +67,190 @@ namespace coreutils { temp >> tempInt; return tempInt; } - + std::string ZString::str() { return std::string(data, length); } - + std::string ZString::str(int len) { return std::string(data, len); } - + std::vector &ZString::split(std::string delimiter, size_t maxSize) { coreutils::ZString zDelimiter((char *)delimiter.c_str(), delimiter.size()); return split(zDelimiter, maxSize); } - + std::vector &ZString::split(ZString &delimiter, size_t maxSize) { list.clear(); if(length == 0) { - list.push_back(ZString("")); - return list; + list.push_back(ZString("")); + return list; } - + char *end = data + length; char *pos = cursor; - - while(pos < end) { + while((pos + delimiter.getLength()) < end) { if(strncmp(pos, delimiter.getData(), delimiter.getLength()) == 0) { - list.push_back(ZString(cursor, pos - cursor)); - cursor = pos + delimiter.getLength(); - pos = cursor; - } - else { - ++pos; - } + list.push_back(ZString(cursor, pos - cursor)); + cursor = pos + delimiter.getLength(); + pos = cursor; + } + else { + ++pos; + } } + pos += delimiter.getLength(); list.push_back(ZString(cursor, pos - cursor)); cursor = pos; return list; } - + + bool ZString::isCharacter(char ch, const char *string) { + int len = strlen(string); + for(int ix = 0; ix < len; ++ix) { + if(ch == string[ix]) + return true; + } + return false; + } + ZString ZString::getTokenInclude(const char *include) { char *start = cursor; - int len = strcspn(cursor, include); - cursor += len; - return ZString(start, len); + while((cursor <= (data + length)) && isCharacter(*cursor, include)) + ++cursor; + return ZString(start, cursor - start); } - + ZString ZString::getTokenExclude(const char *exclude) { char *start = cursor; - int len = strspn(cursor, exclude); - cursor += len; - return ZString(start, len); + while((cursor <= (data + length)) && !isCharacter(*cursor, exclude)) + ++cursor; + return ZString(start, cursor - start); } - + ZString ZString::getTokenExclude(std::string exclude) { return getTokenExclude(exclude.c_str()); } - + ZString &ZString::operator[](int index) { return list[index]; } - + bool ZString::eod() { return cursor >= data + length; } - + bool ZString::equals(const char *value) { if(strlen(value) != length) return false; return strncmp(data, value, length) == 0; } - + bool ZString::equals(char *value) { if(strlen(value) != length) return false; return strncmp(data, value, length) == 0; } - + bool ZString::equals(ZString &zstring) { - if(zstring.getLength() != getLength()) - return false; - return strncmp(data, zstring.getData(), getLength()) == 0; + if(zstring.getLength() != length) + return false; + return strncmp(data, zstring.getData(), length) == 0; } - + bool ZString::equals(std::string &string) { return string == std::string(data, length); } - + bool ZString::ifNext(const char *value) { - bool test = (strncmp(cursor, value, strlen(value)) == 0); + if(((data + length) - cursor) < strlen(value)) + return false; + bool test = (strncmp(cursor, value, strlen(value)) == 0); if(test) cursor += strlen(value); return test; } - + + int ZString::ifEqualsCount(ZString &comparator) { + int count = 0; + while(cursor < (data + length)) { + if(*cursor == *comparator.cursor) { + ++count; + ++cursor; + ++comparator.cursor; + } + else { + return count; + } + } + return count; + } + int ZString::skipWhitespace() { int len = strspn(cursor, " \t"); cursor += len; return len; } - + ZString ZString::goeol() { - char* temp = cursor; - cursor += strspn(cursor, "\r\n"); - return ZString(temp, cursor-- - temp); + bool set = false; + char *temp = cursor; + char *tempend = data + length; + while(cursor <= (data + length)) { + if(*cursor == '\r') { + tempend = cursor++; + set = true; + } + if(*cursor == '\n') { + if(!set) + tempend = cursor; + ++cursor; + break; + } + ++cursor; + } + return ZString(temp, tempend - temp); } - + ZString ZString::readBlock(size_t size) { char *temp = cursor; cursor += size; return ZString(temp, size); } - + char* ZString::getData() { return data; } - + size_t ZString::getLength() { - return length; + return length - (cursor - data); } - + void ZString::setZString(ZString zstring) { data = zstring.getData(); - length = zstring.getLength(); + length = zstring.getLength(); cursor = data; } - + + void ZString::reset() { + cursor = data; + } + + char ZString::charAt(int index) { + return *(data + index); + } + + bool ZString::ifCRLF() { + int len = length; + if(*(data + length - 1) == '\n') + --length; + if(*(data + length - 1) == '\r') + --length; + if(cursor > (data + length)) + cursor = data + length; + return len != length; + } + + } diff --git a/ZString.h b/ZString.h index 2021adb..0a63085 100644 --- a/ZString.h +++ b/ZString.h @@ -1,24 +1,27 @@ #ifndef __ZString_h__ #define __ZString_h__ -#include "includes" +#include +#include +#include +#include namespace coreutils { /// /// Use the ZString object when advanced parsing algorithms are required to simplify - /// parsing. ZString is not a backing store and requires that any referenced buffer + /// parsing. ZString is not a backing store and requires that any referenced buffer /// or objects are retained throughout the life of the object. Additionally, ZString /// is non-destructive to its underlying references. /// /// ZString provides several methods to reference and parse the content. First method - /// is parse(ZString delimiter) which will return a vector of ZString which contains + /// is split(ZString delimiter) which will return a vector of ZString which contains /// references to the parts of the string split by the provided delimiter. The delimiter /// portion is omitted from the results. /// - /// Second method involves a cursor which is a pointer to data contained within the + /// Second method involves a cursor which is a pointer to data contained within the /// ZString and is used to point to the current parsing point. Several methods are - /// provided to advance through the parsing based upon content and rule checks. + /// provided to advance through the parsing based upon content and rule checks. /// class ZString { @@ -34,9 +37,9 @@ namespace coreutils { /// /// /// - + ZString(const char *data); - + /// /// Consructor providing the initial setup of the ZString object. /// @@ -51,6 +54,12 @@ namespace coreutils { ZString(const ZString &zstring); + /// + /// Consructor from a string. + /// + + ZString(std::string string); + /// /// A friend method used to write the value of the ZString from the cursor /// point to an ostream using the << syntax. @@ -60,6 +69,10 @@ namespace coreutils { friend std::ostream& operator<<(std::ostream& os, const std::string& string); friend std::ostream& operator+(std::ostream& os, const ZString& zstring); + bool operator<(const ZString &valuex) const; + bool operator>(const ZString &valuex) const; + bool operator==(const ZString &valuex) const; + /// /// Return a vector of ZString objects which contain the parts established /// by using the split method and passing a delimiter value. @@ -101,8 +114,8 @@ namespace coreutils { /// /// Use getTokenInclude with a list of character to allow the forwarding - /// of the cursor through the data until a character that is not in the - /// include string is not encountered in the ZString data. + /// of the cursor through the data until a character that is not in the + /// include string is not encountered in the ZString data. /// ZString getTokenInclude(const char *include); @@ -158,6 +171,8 @@ namespace coreutils { bool ifNext(const char *value); + int ifEqualsCount(ZString &comparator); + /// /// Advance the cursor through the ZString for each whitespace character /// encountered. @@ -173,7 +188,7 @@ namespace coreutils { /// /// Return a block of data as a ZString from the cursor location for - /// the number of bytes specified by size. + /// the number of bytes specified by size. /// ZString readBlock(size_t size); @@ -182,29 +197,47 @@ namespace coreutils { /// Return a pointer to the beginning of the ZString data. /// - char* getData(); + char* getData(); /// - /// Return the length of the ZString. + /// Return the length of the ZString. /// size_t getLength(); - + /// /// Set this ZString to have the same data space as the ZString pointer /// passed into the method. /// - + void setZString(ZString zstring); - size_t length; - + /// + /// + /// + + void reset(); + + /// + /// + /// + + char charAt(int index); + + /// + /// + /// + + bool ifCRLF(); + private: char *data; -// size_t length; + size_t length; char *cursor; std::vector list; + bool isCharacter(char ch, const char *string); + }; } diff --git a/compile b/compile index 5d5037e..93380a0 100755 --- a/compile +++ b/compile @@ -27,4 +27,7 @@ else exit -1 fi +rm *.o +rm *~ + diff --git a/testing/http_request.data b/testing/http_request.data new file mode 100644 index 0000000..e1dc623 --- /dev/null +++ b/testing/http_request.data @@ -0,0 +1,17 @@ +GET / HTTP/1.1 +Host: localhost:8080 +Connection: keep-alive +Cache-Control: max-age=0 +sec-ch-ua: "Chromium";v="92", " Not A;Brand";v="99", "Google Chrome";v="92" +sec-ch-ua-mobile: ?0 +Upgrade-Insecure-Requests: 1 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10; rv:33.0) Gecko/20100101 Firefox/33.0 +Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9 +Sec-Fetch-Site: none +Sec-Fetch-Mode: navigate +Sec-Fetch-User: ?1 +Sec-Fetch-Dest: document +Accept-Encoding: gzip, deflate, br +Accept-Language: en-US,en;q=0.9,fr-CA;q=0.8,fr;q=0.7 +Cookie: _ga=GA1.1.1017526412.1628195401 + diff --git a/testing/imfmessage_test b/testing/imfmessage_test new file mode 100755 index 0000000..4911505 Binary files /dev/null and b/testing/imfmessage_test differ diff --git a/testing/imfmessage_test.cpp b/testing/imfmessage_test.cpp new file mode 100644 index 0000000..c1b3af6 --- /dev/null +++ b/testing/imfmessage_test.cpp @@ -0,0 +1,26 @@ +#include +#include "../IMFMessage.h" + +int main(int argc, char **argv) { + + coreutils::ZString buffer("Host: localhost:8080\r\n" + "Connection: keep-alive\r\n" + "Cache-Control: max-age=0\r\n" + "sec-ch-ua: \"Chromium\";v=\"92\", \" Not A;Brand\";v=\"99\", \"Google Chrome\";v=\"92\"\r\n" + "sec-ch-ua-mobile: ?0\r\n" + "Upgrade-Insecure-Requests: 1\r\n" + "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10; rv:33.0) Gecko/20100101 Firefox/33.0\r\n" + "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9\r\n" + "Sec-Fetch-Site: none\r\n" + "Sec-Fetch-Mode: navigate\r\n" + "Sec-Fetch-User: ?1\r\n" + "Sec-Fetch-Dest: document\r\n" + "Accept-Encoding: gzip, deflate, br\r\n" + "Accept-Language: en-US,en;q=0.9,fr-CA;q=0.8,fr;q=0.7\r\n" + "Cookie: _ga=GA1.1.1017526412.1628195401\r\n" + "\r\n"); + + coreutils::IMFMessage message(buffer); + + return 0; +} diff --git a/testing/zstring_test b/testing/zstring_test index fdb3c3a..fcf6ca2 100755 Binary files a/testing/zstring_test and b/testing/zstring_test differ diff --git a/testing/zstring_test.cpp b/testing/zstring_test.cpp index 1adba88..b2be98f 100644 --- a/testing/zstring_test.cpp +++ b/testing/zstring_test.cpp @@ -4,14 +4,52 @@ int main(int argc, char **argv) { coreutils::ZString test("character1111:22222:33333"); - test.length = 9; + std::cout << "test pre-split: [" << test << "]." << std::endl; test.split(":"); - std::cout << test << std::endl; + std::cout << "test post-split: [" << test << "]." << std::endl; + std::cout << "test sections: [" << test.getList().size() << "]." << std::endl; std::cout << test.getLength() << std::endl; std::cout << test[0] << std::endl; std::cout << test[1] << std::endl; + std::cout << test[2] << std::endl; + + coreutils::ZString test2("character1111:::::22222:::::33333"); + + test2.split(":::::"); + + std::cout << "test string: [" << test2 << "]" << std::endl; + std::cout << "length: [" << test2.getLength() << "]" << std::endl; + + std::cout << "[" << test2[0] << "]" << std::endl; + std::cout << "[" << test2[1] << "]" << std::endl; + std::cout << "[" << test2[2] << "]" << std::endl; + std::cout << "[" << test2[3] << "]" << std::endl; + + coreutils::ZString boundary("----WebKitFormBoundary5hx9ixjfxtJ8nXNm"); + + coreutils::ZString test3("------WebKitFormBoundary5hx9ixjfxtJ8nXNm\r\n" + "Content-Disposition: form-data; name=\"username\"\r\n" + "\r\n" + "test\r\n" + "------WebKitFormBoundary5hx9ixjfxtJ8nXNm\r\n" + "Content-Disposition: form-data; name=\"password\"\r\n" + "\r\n" + "test\r\n" + "------WebKitFormBoundary5hx9ixjfxtJ8nXNm\r\n" + "Content-Disposition: form-data; name=\"verify\"\r\n" + "\r\n" + "test\r\n" + "------WebKitFormBoundary5hx9ixjfxtJ8nXNm--\r\n"); + + test3.split(boundary); + + std::cout << "[" << test3[0] << "]" << std::endl; + std::cout << "[" << test3[1] << "]" << std::endl; + std::cout << "[" << test3[2] << "]" << std::endl; + std::cout << "[" << test3[3] << "]" << std::endl; + }