Skip to content

Commit

Permalink
csv: add support for printing a csv_record
Browse files Browse the repository at this point in the history
  • Loading branch information
razvancrainea authored and bogdan-iancu committed Apr 18, 2024
1 parent bc6db7a commit cf17530
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 0 deletions.
75 changes: 75 additions & 0 deletions lib/csv.c
Original file line number Diff line number Diff line change
Expand Up @@ -243,3 +243,78 @@ void free_csv_record(csv_record *record)
free_f(prev);
}
}

static int check_quote_csv_record(str *val, int *escape)
{
char *p;
int quote = 0;
*escape = 0;

for (p = val->s; p < val->s + val->len; p++) {
switch (*p) {
case '"':
(*escape)++;
/* fallthrough */
case ',':
case '\n':
quote = 1;
break;
}
}
return quote;
}

str *__print_csv_record(csv_record *record, enum csv_flags print_flags,
unsigned char sep)
{
static str ret;
str_list *it;
int len = -1, esc;
char *p, *c;

if (print_flags & CSV_SHM)
malloc_f = osips_shm_malloc;
else
malloc_f = osips_pkg_malloc;

for (it = record; it; it = it->next) {
len += 1 /* sep */ + it->s.len;
/* check to see if ne need to encode */
if (check_quote_csv_record(&it->s, &esc))
len += 2 + esc;
}

ret.s = malloc_f(len);
if (!ret.s)
return NULL;
p = ret.s;
for (it = record; it; it = it->next) {
if (it != record)
*p++ = sep;

if (check_quote_csv_record(&it->s, &esc)) {
if (!esc) {
/* simply add the quotes */
*p++ = '"';
memcpy(p, it->s.s, it->s.len);
p+= it->s.len;
*p++ = '"';
} else {
for (c = it->s.s; c < it->s.s + it->s.len; c++) {
switch (*c) {
case '"':
*p++ = '"';
break;
}
*p++ = *c;
}
}
} else {
/* simply copy the content */
memcpy(p, it->s.s, it->s.len);
p += it->s.len;
}
}
ret.len = len;
return &ret;
}
5 changes: 5 additions & 0 deletions lib/csv.h
Original file line number Diff line number Diff line change
Expand Up @@ -56,4 +56,9 @@ csv_record *__parse_csv_record(const str *in, enum csv_flags parse_flags,
/* Easily free your CSV records, regardless of any flags set during parsing */
void free_csv_record(csv_record *record);

str *__print_csv_record(csv_record *record, enum csv_flags print_flags,
unsigned char sep);
#define _print_csv_record(in, flags) __print_csv_record(in, flags, ',')
#define print_csv_record(in) _print_csv_record(in, 0)

#endif /* __LIB_CSV__ */

0 comments on commit cf17530

Please sign in to comment.