// text.cpp - Text functions. // // (c) 2016-2017 Xestia Software Development. // // This file is part of Xestia Calendar. // // Xestia Calendar is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by the // Free Software Foundation, version 3 of the license. // // Xestia Calendar is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License along // with Xestia Calendar. If not, see #include "text.h" using namespace std; multimap ProcessTextVectors(vector *TextProperties, vector *TextValues, bool SearchMultiple, string Property){ multimap ProcessResult; // Go through each of the values. int TextSeekCount = 0; int TextPropertySize = 0; int PropertySeekCount = 0; string PropertyName = ""; int PropertyNameSize = 0; char BufferChar = 0; for (vector::iterator iter = TextProperties->begin(); iter != TextProperties->end(); iter++){ TextPropertySize = iter->size(); if (TextPropertySize == 0){ // Text property size is 0. Go to the next // pair. continue; } // Get the property data up to the first semi-colon. while (TextSeekCount < TextPropertySize){ BufferChar = (*iter)[TextSeekCount]; if (BufferChar == ';'){ break; } PropertyName += BufferChar; TextSeekCount++; } if (*iter == Property || PropertyName == Property){ ProcessResult.insert(make_pair((*TextProperties)[PropertySeekCount], (*TextValues)[PropertySeekCount])); // Check to continue if one is found. if (SearchMultiple == false){ // Found one, don't search for anymore. break; } } PropertySeekCount++; TextPropertySize = 0; TextSeekCount = 0; PropertyName.clear(); } return ProcessResult; } map SplitValues(string InputData){ map FinalSplitValues; map SplitPoints; map SplitLength; size_t intPropertyLen = InputData.size(); int intSplitsFound = 0; int intSplitSize = 0; int intSplitSeek = 0; int intPrevSplitFound = 0; // Get the split points. for (int i = 0; i <= intPropertyLen; i++){ intSplitSize++; InputData.substr(intPrevSplitFound, intSplitSize); if (InputData.substr(i, 1) == ";" && InputData.substr((i - 1), 1) != "\\"){ if (intSplitsFound > 0){ // Split the value into two. PropertyNameValue NVData = SplitNameValue(InputData.substr(intPrevSplitFound, (intSplitSize - 1))); if (FinalSplitValues.find(NVData.Name) != FinalSplitValues.end()){ FinalSplitValues.insert(make_pair(NVData.Name, NVData.Value)); } else { FinalSplitValues[NVData.Name] = NVData.Value; } } intPrevSplitFound = i + 1; intSplitSize = 0; intSplitsFound++; } } if (intSplitsFound > 0){ PropertyNameValue NVData = SplitNameValue(InputData.substr(intPrevSplitFound, (intSplitSize - 1))); if (FinalSplitValues.find(NVData.Name) != FinalSplitValues.end()){ FinalSplitValues.insert(make_pair(NVData.Name, NVData.Value)); } else { FinalSplitValues[NVData.Name] = NVData.Value; } } return FinalSplitValues; } PropertyNameValue SplitNameValue(string InputData){ PropertyNameValue FinalNameValue; int InputDataLength = InputData.size(); int SeekCount = 0; bool QuoteMode = false; bool DataFound = false; while (SeekCount < InputDataLength){ if (InputData[SeekCount] == '='){ FinalNameValue.Name = InputData.substr(0, SeekCount); try{ FinalNameValue.Value = InputData.substr((SeekCount + 1)); } catch (const out_of_range &oor){ // Do nothing. Have an empty final value. } DataFound = true; break; } SeekCount++; } if (DataFound == false){ FinalNameValue.Name = InputData; } // Check if the value has quotes at the start and end. // Remove them if this is the case. if (FinalNameValue.Value.front() == '\"' && FinalNameValue.Value.back() == '\"'){ FinalNameValue.Value.erase(0, 1); FinalNameValue.Value.erase((FinalNameValue.Value.size() - 1), 1); } return FinalNameValue; } bool HexToInt(std::string *HexString, int *Number){ // Check that each character in the string is a number // or a letter (a-f/A-F). char Char = 0; int CharNum = 0; for (int CharSeek = 0; CharSeek < HexString->size(); CharSeek++){ // Check if character is a number (0-9). Char = HexString->at(CharSeek); CharNum = Char; if (CharNum >= 48 && CharNum <= 57){ continue; } // Check if character is a letter (A-F) if (CharNum >= 65 && CharNum <= 70){ continue; } // Check if character is a letter (a-f). if (CharNum >= 97 && CharNum <= 102){ continue; } // Exit from subroutine as character is invalid. return false; } // Convert a Hex value that is in string to integer. try { *Number = stoi((*HexString), nullptr, 16); } catch (const std::invalid_argument &err){ return false; } catch (const std::out_of_range &err){ return false; } return true; } bool IntToHex(int *Number, std::string *HexString, int HexFill){ stringstream StringData; StringData << setfill('0') << hex << setw(HexFill) << (*Number); (*HexString) = StringData.str(); return true; } void SplitPathFilename(string *CalendarEntryHREF, string *EntryURIPath, string *EntryFilename){ // Look for the last forward slash. int LastForwardSlash = -1; int CharSeek = 0; string StringIterChar = ""; for (string::iterator StringIter = CalendarEntryHREF->begin(); StringIter != CalendarEntryHREF->end(); StringIter++){ StringIterChar = *StringIter; if (StringIterChar == "/"){ LastForwardSlash = CharSeek; } CharSeek++; } if (LastForwardSlash == -1){ return; } // Get the string before the last hash for the path. (*EntryURIPath) = CalendarEntryHREF->substr(0, (LastForwardSlash + 1)); // Get the string after the last hash for the filename. (*EntryFilename) = CalendarEntryHREF->substr((LastForwardSlash + 1)); } string OutputText(string *TextInput){ string OutputTextData; string OutputLine; int CharSeek = 0; int LineSeek = 0; int MaxLineSeek = 77; for (CharSeek = 0; CharSeek < TextInput->size(); CharSeek++){ LineSeek++; if (LineSeek == MaxLineSeek){ if (TextInput->substr(CharSeek, 1) != "\n"){ OutputLine += TextInput->substr(CharSeek, 1); } OutputLine += "\n"; OutputTextData += OutputLine; OutputLine = " "; LineSeek = 0; MaxLineSeek = 76; continue; } OutputLine += TextInput->substr(CharSeek, 1); } if (OutputLine != " "){ OutputTextData += OutputLine; } return OutputTextData; }