-
Notifications
You must be signed in to change notification settings - Fork 0
/
myVcardReader.cpp
executable file
·148 lines (135 loc) · 4.84 KB
/
myVcardReader.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
#include "myVcardReader.hpp"
#include <assert.h>
// This program aims to parse specifically a vCard file from the purple List Handler plugin. Other libraries exist however, I had trouble getting them working
// (and the libraries are as old as a decade or another niche application so here we go reinventing the wheel, probably due to my ignorance)
/**
* Overview of what we need to do
* We need a function that will take a path to a file
* Build and return a structure of some kind (Probably an array/linked list of Cards)
* Iterate through this array and return desired information (Or allow client to do this?)
*/
vCard::vCard(std::string newName, std::string newPhoneNumber)
{
name = newName;
phoneNumber = newPhoneNumber;
}
vCard::vCard()
{
name = "";
phoneNumber = "";
}
Node::Node(Node *nextNode, vCard *newData)
{
next = nextNode;
data = newData;
}
void LinkedList::add(vCard newData)
{
vCard *tempCardPtr =(vCard *) malloc(sizeof(newData));
new (tempCardPtr) vCard(newData);
Node *tempNode = (Node *) malloc(sizeof(Node));
tempNode->next = nullptr;
tempNode->data = tempCardPtr;
if (tail == nullptr) {
tail = tempNode;
head = tail;
} else {
tail->next = tempNode;
tail = tail->next;
}
}
void destroyNode(Node* nodeToDestroy)
{
if (nodeToDestroy == nullptr)
//This means the initial call used a null pointer so termination case
return;
if (nodeToDestroy->next != nullptr)
destroyNode(nodeToDestroy->next);
std::free(nodeToDestroy->next);
std::free(nodeToDestroy->data);
}
//Function that destroys our list (since we malloc the memory)
void destroyLinkedList(LinkedList *listToDestroy)
{
destroyNode(listToDestroy->head);
free(listToDestroy->head);
std::free(listToDestroy);
}
// Function that creates our List from a given file
/**
* Creates a linked list of vCard structs from a file
*/
LinkedList *buildFromFile(std::string filename)
{
std::ifstream file{ filename };
if (!file) {
std::cerr << "Cannot open " + filename + "for writing.\n";
return (LinkedList *)nullptr;
}
// Create the List here
LinkedList *vCardList = (LinkedList *) malloc(sizeof(LinkedList));
vCardList->head = nullptr;
vCardList->size = 0;
while (file) {
std::string line;
std::getline(file, line);
//Not recognizing the start of the VCARD. Maybe some kind of line ending issue?
//Look at the actual characters in 'line'
//Create a vCard here (We assume the file has "BEGIN::VCARD ... END:VCARD")
//This is in case the file was created under a windows system or uses carriage returns for
//whatever reason.
int carriageReturnLoc = line.find_last_of('\r');
line = line.substr(0, carriageReturnLoc);
if (line == "BEGIN:VCARD") {
// loop through the lines until we reach "END:VCARD". We will use a counter and terminate if we have more than 100 iterations
// (prevent infinite loops and these vCards will never be that long)
if (!file) {
//Failure case. Terminate after freeing our memory
std::cout << "Error.\n";
destroyLinkedList(vCardList);
}
int count = 0;
std::string vcardLine;
std::string name;
std::string phoneNumber = "";
std::getline(file, vcardLine);
carriageReturnLoc = vcardLine.find_last_of('\r');
vcardLine = vcardLine.substr(0, carriageReturnLoc);
while (count <= 100 && vcardLine != "END:VCARD") {
if (!file) {
//Failure case. Terminate after freeing our memory
destroyLinkedList(vCardList);
}
//we must read in the line and check if it is one of the two that we need
if (vcardLine.substr(0, 2) == "FN") {
// Full name of contact
name = vcardLine.substr(3, vcardLine.npos);
} else if (vcardLine.substr(0,3) == "TEL") {
// This line contains the phone number. We may also have several numbers for one contact (Cell, Work, etc) For now, we ignore all after the first
// But we will support this behavior (Create a new vCard object?)
if (phoneNumber != "")
continue;
// We search through the line to get the last ':' char and copy the rest of this line into a new string
std::string tempLine = vcardLine.substr(vcardLine.find_last_of(':') + 1); //Doesn't do error checking if no ':' are present
//Now, we need to create a new string containing everything except the '-' chars
std::string phoneNumber = "";
for (std::string::iterator it=tempLine.begin(); it!=tempLine.end(); ++it) {
char currentChar = *it;
if (currentChar != '-') {
phoneNumber.append(1u, currentChar);
}
}
//Now, we create the vCard object and add it to our list
vCard tempCard(name, phoneNumber);
//vCard *addingCard =
vCardList->add(tempCard);
}
count++;
std::getline(file, vcardLine);
}
}
}
std::cout << "File done.\n";
assert(vCardList->tail->next == nullptr);
return vCardList;
}