Page Menu
Home
Phorge
Search
Configure Global Search
Log In
Files
F1497855
csvparser.c
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Size
8 KB
Referenced Files
None
Subscribers
None
csvparser.c
View Options
#include
<stdlib.h>
#include
<string.h>
#include
<stdio.h>
#include
<errno.h>
#include
"csvparser.h"
#ifdef __cplusplus
extern
"C"
{
#endif
CsvParser
*
CsvParser_new
(
const
char
*
filePath
,
const
char
*
delimiter
,
int
firstLineIsHeader
)
{
CsvParser
*
csvParser
=
(
CsvParser
*
)
malloc
(
sizeof
(
CsvParser
));
if
(
filePath
==
NULL
)
{
csvParser
->
filePath_
=
NULL
;
}
else
{
int
filePathLen
=
strlen
(
filePath
);
csvParser
->
filePath_
=
(
char
*
)
malloc
((
filePathLen
+
1
));
strcpy
(
csvParser
->
filePath_
,
filePath
);
}
csvParser
->
firstLineIsHeader_
=
firstLineIsHeader
;
csvParser
->
errMsg_
=
NULL
;
if
(
delimiter
==
NULL
)
{
csvParser
->
delimiter_
=
','
;
}
else
if
(
_CsvParser_delimiterIsAccepted
(
delimiter
))
{
csvParser
->
delimiter_
=
*
delimiter
;
}
else
{
csvParser
->
delimiter_
=
'\0'
;
}
csvParser
->
header_
=
NULL
;
csvParser
->
fileHandler_
=
NULL
;
csvParser
->
fromString_
=
0
;
csvParser
->
csvString_
=
NULL
;
csvParser
->
csvStringIter_
=
0
;
return
csvParser
;
}
CsvParser
*
CsvParser_new_from_string
(
const
char
*
csvString
,
const
char
*
delimiter
,
int
firstLineIsHeader
)
{
CsvParser
*
csvParser
=
CsvParser_new
(
NULL
,
delimiter
,
firstLineIsHeader
);
csvParser
->
fromString_
=
1
;
if
(
csvString
!=
NULL
)
{
int
csvStringLen
=
strlen
(
csvString
);
csvParser
->
csvString_
=
(
char
*
)
malloc
(
csvStringLen
+
1
);
strcpy
(
csvParser
->
csvString_
,
csvString
);
}
return
csvParser
;
}
void
CsvParser_destroy
(
CsvParser
*
csvParser
)
{
if
(
csvParser
==
NULL
)
{
return
;
}
if
(
csvParser
->
filePath_
!=
NULL
)
{
free
(
csvParser
->
filePath_
);
}
if
(
csvParser
->
errMsg_
!=
NULL
)
{
free
(
csvParser
->
errMsg_
);
}
if
(
csvParser
->
fileHandler_
!=
NULL
)
{
fclose
(
csvParser
->
fileHandler_
);
}
if
(
csvParser
->
header_
!=
NULL
)
{
CsvParser_destroy_row
(
csvParser
->
header_
);
}
if
(
csvParser
->
csvString_
!=
NULL
)
{
free
(
csvParser
->
csvString_
);
}
free
(
csvParser
);
}
void
CsvParser_destroy_row
(
CsvRow
*
csvRow
)
{
int
i
;
for
(
i
=
0
;
i
<
csvRow
->
numOfFields_
;
i
++
)
{
free
(
csvRow
->
fields_
[
i
]);
}
free
(
csvRow
->
fields_
);
free
(
csvRow
);
}
CsvRow
*
CsvParser_getHeader
(
CsvParser
*
csvParser
)
{
if
(
!
csvParser
->
firstLineIsHeader_
)
{
_CsvParser_setErrorMessage
(
csvParser
,
"Cannot supply header, as current CsvParser object does not support header"
);
return
NULL
;
}
if
(
csvParser
->
header_
==
NULL
)
{
csvParser
->
header_
=
_CsvParser_getRow
(
csvParser
);
}
return
csvParser
->
header_
;
}
CsvRow
*
CsvParser_getRow
(
CsvParser
*
csvParser
)
{
if
(
csvParser
->
firstLineIsHeader_
&&
csvParser
->
header_
==
NULL
)
{
csvParser
->
header_
=
_CsvParser_getRow
(
csvParser
);
}
return
_CsvParser_getRow
(
csvParser
);
}
int
CsvParser_getNumFields
(
CsvRow
*
csvRow
)
{
return
csvRow
->
numOfFields_
;
}
const
char
**
CsvParser_getFields
(
CsvRow
*
csvRow
)
{
return
(
const
char
**
)
csvRow
->
fields_
;
}
CsvRow
*
_CsvParser_getRow
(
CsvParser
*
csvParser
)
{
int
numRowRealloc
=
0
;
int
acceptedFields
=
64
;
int
acceptedCharsInField
=
64
;
if
(
csvParser
->
filePath_
==
NULL
&&
(
!
csvParser
->
fromString_
))
{
_CsvParser_setErrorMessage
(
csvParser
,
"Supplied CSV file path is NULL"
);
return
NULL
;
}
if
(
csvParser
->
csvString_
==
NULL
&&
csvParser
->
fromString_
)
{
_CsvParser_setErrorMessage
(
csvParser
,
"Supplied CSV string is NULL"
);
return
NULL
;
}
if
(
csvParser
->
delimiter_
==
'\0'
)
{
_CsvParser_setErrorMessage
(
csvParser
,
"Supplied delimiter is not supported"
);
return
NULL
;
}
if
(
!
csvParser
->
fromString_
)
{
if
(
csvParser
->
fileHandler_
==
NULL
)
{
csvParser
->
fileHandler_
=
fopen
(
csvParser
->
filePath_
,
"r"
);
if
(
csvParser
->
fileHandler_
==
NULL
)
{
int
errorNum
=
errno
;
const
char
*
errStr
=
strerror
(
errorNum
);
char
*
errMsg
=
(
char
*
)
malloc
(
1024
+
strlen
(
errStr
));
strcpy
(
errMsg
,
""
);
sprintf
(
errMsg
,
"Error opening CSV file for reading: %s : %s"
,
csvParser
->
filePath_
,
errStr
);
_CsvParser_setErrorMessage
(
csvParser
,
errMsg
);
free
(
errMsg
);
return
NULL
;
}
}
}
CsvRow
*
csvRow
=
(
CsvRow
*
)
malloc
(
sizeof
(
CsvRow
));
csvRow
->
fields_
=
(
char
**
)
malloc
(
acceptedFields
*
sizeof
(
char
*
));
csvRow
->
numOfFields_
=
0
;
int
fieldIter
=
0
;
char
*
currField
=
(
char
*
)
malloc
(
acceptedCharsInField
);
int
inside_complex_field
=
0
;
int
currFieldCharIter
=
0
;
int
seriesOfQuotesLength
=
0
;
int
lastCharIsQuote
=
0
;
int
isEndOfFile
=
0
;
while
(
1
)
{
char
currChar
=
(
csvParser
->
fromString_
)
?
csvParser
->
csvString_
[
csvParser
->
csvStringIter_
]
:
fgetc
(
csvParser
->
fileHandler_
);
csvParser
->
csvStringIter_
++
;
int
endOfFileIndicator
;
if
(
csvParser
->
fromString_
)
{
endOfFileIndicator
=
(
currChar
==
'\0'
);
}
else
{
endOfFileIndicator
=
feof
(
csvParser
->
fileHandler_
);
}
if
(
endOfFileIndicator
)
{
if
(
currFieldCharIter
==
0
&&
fieldIter
==
0
)
{
_CsvParser_setErrorMessage
(
csvParser
,
"Reached EOF"
);
free
(
currField
);
CsvParser_destroy_row
(
csvRow
);
return
NULL
;
}
currChar
=
'\n'
;
isEndOfFile
=
1
;
}
if
(
currChar
==
'\r'
)
{
continue
;
}
if
(
currFieldCharIter
==
0
&&
!
lastCharIsQuote
)
{
if
(
currChar
==
'\"'
)
{
inside_complex_field
=
1
;
lastCharIsQuote
=
1
;
continue
;
}
}
else
if
(
currChar
==
'\"'
)
{
seriesOfQuotesLength
++
;
inside_complex_field
=
(
seriesOfQuotesLength
%
2
==
0
);
if
(
inside_complex_field
)
{
currFieldCharIter
--
;
}
}
else
{
seriesOfQuotesLength
=
0
;
}
if
(
isEndOfFile
||
((
currChar
==
csvParser
->
delimiter_
||
currChar
==
'\n'
)
&&
!
inside_complex_field
)
){
currField
[
lastCharIsQuote
?
currFieldCharIter
-
1
:
currFieldCharIter
]
=
'\0'
;
csvRow
->
fields_
[
fieldIter
]
=
(
char
*
)
malloc
(
currFieldCharIter
+
1
);
strcpy
(
csvRow
->
fields_
[
fieldIter
],
currField
);
free
(
currField
);
csvRow
->
numOfFields_
++
;
if
(
currChar
==
'\n'
)
{
return
csvRow
;
}
if
(
csvRow
->
numOfFields_
!=
0
&&
csvRow
->
numOfFields_
%
acceptedFields
==
0
)
{
csvRow
->
fields_
=
(
char
**
)
realloc
(
csvRow
->
fields_
,
((
numRowRealloc
+
2
)
*
acceptedFields
)
*
sizeof
(
char
*
));
numRowRealloc
++
;
}
acceptedCharsInField
=
64
;
currField
=
(
char
*
)
malloc
(
acceptedCharsInField
);
currFieldCharIter
=
0
;
fieldIter
++
;
inside_complex_field
=
0
;
}
else
{
currField
[
currFieldCharIter
]
=
currChar
;
currFieldCharIter
++
;
if
(
currFieldCharIter
==
acceptedCharsInField
-
1
)
{
acceptedCharsInField
*=
2
;
currField
=
(
char
*
)
realloc
(
currField
,
acceptedCharsInField
);
}
}
lastCharIsQuote
=
(
currChar
==
'\"'
)
?
1
:
0
;
}
}
int
_CsvParser_delimiterIsAccepted
(
const
char
*
delimiter
)
{
char
actualDelimiter
=
*
delimiter
;
if
(
actualDelimiter
==
'\n'
||
actualDelimiter
==
'\r'
||
actualDelimiter
==
'\0'
||
actualDelimiter
==
'\"'
)
{
return
0
;
}
return
1
;
}
void
_CsvParser_setErrorMessage
(
CsvParser
*
csvParser
,
const
char
*
errorMessage
)
{
if
(
csvParser
->
errMsg_
!=
NULL
)
{
free
(
csvParser
->
errMsg_
);
}
int
errMsgLen
=
strlen
(
errorMessage
);
csvParser
->
errMsg_
=
(
char
*
)
malloc
(
errMsgLen
+
1
);
strcpy
(
csvParser
->
errMsg_
,
errorMessage
);
}
const
char
*
CsvParser_getErrorMessage
(
CsvParser
*
csvParser
)
{
return
csvParser
->
errMsg_
;
}
#ifdef __cplusplus
}
#endif
File Metadata
Details
Attached
Mime Type
text/x-c
Expires
Sun, Mar 1, 10:18 PM (19 h, 33 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
287659
Default Alt Text
csvparser.c (8 KB)
Attached To
Mode
R20 SoC_Rosa_repo
Attached
Detach File
Event Timeline
Log In to Comment