1 // text.cpp - Text functions.
3 // (c) 2016-2017 Xestia Software Development.
5 // This file is part of Xestia Calendar.
7 // Xestia Calendar is free software: you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by the
9 // Free Software Foundation, version 3 of the license.
11 // Xestia Calendar is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with Xestia Calendar. If not, see <http://www.gnu.org/licenses/>
23 multimap<string, string> ProcessTextVectors(vector<string> *textProperties,
24 vector<string> *textValues,
28 multimap<string,string> processResult;
30 // Go through each of the values.
32 int textSeekCount = 0;
33 int textPropertySize = 0;
34 int propertySeekCount = 0;
35 string propertyName = "";
36 int propertyNameSize = 0;
39 for (vector<string>::iterator iter = textProperties->begin();
40 iter != textProperties->end(); iter++){
42 textPropertySize = iter->size();
44 if (textPropertySize == 0){
46 // Text property size is 0. Go to the next
53 // Get the property data up to the first semi-colon.
55 while (textSeekCount < textPropertySize){
57 bufferChar = (*iter)[textSeekCount];
59 if (bufferChar == ';'){
63 propertyName += bufferChar;
69 if (*iter == property || propertyName == property){
71 processResult.insert(make_pair((*textProperties)[propertySeekCount],
72 (*textValues)[propertySeekCount]));
74 // Check to continue if one is found.
76 if (searchMultiple == false){
78 // Found one, don't search for anymore.
97 map<string, string> SplitValues(string inputData){
99 map<string,string> finalSplitValues;
100 map<int,int> splitPoints;
101 map<int,int> splitLength;
102 size_t intPropertyLen = inputData.size();
103 int intSplitsFound = 0;
104 int intSplitSize = 0;
105 int intSplitSeek = 0;
106 int intPrevSplitFound = 0;
108 // Get the split points.
110 for (int i = 0; i <= intPropertyLen; i++){
114 inputData.substr(intPrevSplitFound, intSplitSize);
116 if (inputData.substr(i, 1) == ";" &&
117 inputData.substr((i - 1), 1) != "\\"){
119 if (intSplitsFound > 0){
121 // Split the value into two.
123 PropertyNameValue nVData = SplitNameValue(inputData.substr(intPrevSplitFound, (intSplitSize - 1)));
125 if (finalSplitValues.find(nVData.name) != finalSplitValues.end()){
126 finalSplitValues.insert(make_pair(nVData.name, nVData.value));
128 finalSplitValues[nVData.name] = nVData.value;
133 intPrevSplitFound = i + 1;
141 if (intSplitsFound > 0){
143 PropertyNameValue nVData = SplitNameValue(inputData.substr(intPrevSplitFound, (intSplitSize - 1)));
145 if (finalSplitValues.find(nVData.name) != finalSplitValues.end()){
146 finalSplitValues.insert(make_pair(nVData.name, nVData.value));
148 finalSplitValues[nVData.name] = nVData.value;
153 return finalSplitValues;
157 PropertyNameValue SplitNameValue(string inputData){
159 PropertyNameValue finalNameValue;
160 int inputDataLength = inputData.size();
162 bool quoteMode = false;
163 bool dataFound = false;
165 while (seekCount < inputDataLength){
167 if (inputData[seekCount] == '='){
169 finalNameValue.name = inputData.substr(0, seekCount);
172 finalNameValue.value = inputData.substr((seekCount + 1));
175 catch (const out_of_range &oor){
176 // Do nothing. Have an empty final value.
187 if (dataFound == false){
189 finalNameValue.name = inputData;
193 // Check if the value has quotes at the start and end.
194 // Remove them if this is the case.
196 if (finalNameValue.value.front() == '\"' &&
197 finalNameValue.value.back() == '\"'){
199 finalNameValue.value.erase(0, 1);
200 finalNameValue.value.erase((finalNameValue.value.size() - 1), 1);
204 return finalNameValue;
208 bool HexToInt(std::string *hexString, int *number){
210 // Check that each character in the string is a number
211 // or a letter (a-f/A-F).
216 for (int charSeek = 0;
217 charSeek < hexString->size(); charSeek++){
219 // Check if character is a number (0-9).
221 charLetter = hexString->at(charSeek);
222 charNum = charLetter;
231 // Check if character is a letter (A-F)
240 // Check if character is a letter (a-f).
249 // Exit from subroutine as character is invalid.
255 // Convert a Hex value that is in string to integer.
259 *number = stoi((*hexString), nullptr, 16);
263 catch (const std::invalid_argument &err){
269 catch (const std::out_of_range &err){
279 bool IntToHex(int *number, std::string *hexString, int hexFill){
281 stringstream stringData;
282 stringData << setfill('0') << hex << setw(hexFill) << (*number);
283 (*hexString) = stringData.str();
289 void SplitPathFilename(string *calendarEntryHREF, string *entryURIPath,
290 string *entryFilename){
292 // Look for the last forward slash.
294 int lastForwardSlash = -1;
296 string stringIterChar = "";
298 for (string::iterator stringIter = calendarEntryHREF->begin();
299 stringIter != calendarEntryHREF->end(); stringIter++){
301 stringIterChar = *stringIter;
303 if (stringIterChar == "/"){
304 lastForwardSlash = charSeek;
311 if (lastForwardSlash == -1){
317 // Get the string before the last hash for the path.
319 (*entryURIPath) = calendarEntryHREF->substr(0, (lastForwardSlash + 1));
321 // Get the string after the last hash for the filename.
323 (*entryFilename) = calendarEntryHREF->substr((lastForwardSlash + 1));
327 string OutputText(string *textInput){
329 string outputTextData;
333 int maxLineSeek = 77;
335 for (charSeek = 0; charSeek < textInput->size(); charSeek++){
339 if (lineSeek == maxLineSeek){
341 if (textInput->substr(charSeek, 1) != "\n"){
342 outputLine += textInput->substr(charSeek, 1);
345 outputTextData += outputLine;
353 outputLine += textInput->substr(charSeek, 1);
357 if (outputLine != " "){
359 outputTextData += outputLine;
363 return outputTextData;