// 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 charLetter = 0;
int charNum = 0;
for (int charSeek = 0;
charSeek < hexString->size(); charSeek++){
// Check if character is a number (0-9).
charLetter = hexString->at(charSeek);
charNum = charLetter;
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;
}