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 Char = HexString->at(CharSeek);
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;