@@ -60,6 +60,28 @@ tup(x::AbstractString) = Tuple(codeunits(x))
6060tlen (:: UInt8 ) = 1
6161tlen (:: NTuple{N, UInt8} ) where {N} = N
6262
63+ function Options (;
64+ delim:: Union{Char, String} = ' ,' ,
65+ quotechar:: Char = ' "' ,
66+ openquotechar:: Union{Char, Nothing} = nothing ,
67+ closequotechar:: Union{Char, Nothing} = nothing ,
68+ escapechar:: Char = ' "' ,
69+ newline:: Union{Char, String} = ' \n ' ,
70+ decimal:: Char = ' .' ,
71+ dateformat= nothing ,
72+ quotestrings:: Bool = false ,
73+ missingstring:: AbstractString = " " ,
74+ transform:: Function = _identity,
75+ bom:: Bool = false ,
76+ kw...
77+ )
78+ checkvaliddelim (delim)
79+ (isascii (something (openquotechar, quotechar)) && isascii (something (closequotechar, quotechar)) && isascii (escapechar)) || throw (ArgumentError (" quote and escape characters must be ASCII characters " ))
80+ oq, cq = openquotechar != = nothing ? (openquotechar % UInt8, closequotechar % UInt8) : (quotechar % UInt8, quotechar % UInt8)
81+ e = escapechar % UInt8
82+ return Options (tup (delim), oq, cq, e, tup (newline), decimal % UInt8, dateformat, quotestrings, tup (missingstring), transform, bom)
83+ end
84+
6385"""
6486 CSV.RowWriter(table; kwargs...)
6587
@@ -97,26 +119,11 @@ Base.eltype(r::RowWriter) = String
97119_identity (col, val) = val
98120
99121function RowWriter (table;
100- delim:: Union{Char, String} = ' ,' ,
101- quotechar:: Char = ' "' ,
102- openquotechar:: Union{Char, Nothing} = nothing ,
103- closequotechar:: Union{Char, Nothing} = nothing ,
104- escapechar:: Char = ' "' ,
105- newline:: Union{Char, String} = ' \n ' ,
106- decimal:: Char = ' .' ,
107- dateformat= nothing ,
108- quotestrings:: Bool = false ,
109- missingstring:: AbstractString = " " ,
110- transform:: Function = _identity,
111- bom:: Bool = false ,
112122 header:: Vector = String[],
113123 writeheader:: Bool = true ,
114- bufsize:: Int = 2 ^ 22 )
115- checkvaliddelim (delim)
116- (isascii (something (openquotechar, quotechar)) && isascii (something (closequotechar, quotechar)) && isascii (escapechar)) || throw (ArgumentError (" quote and escape characters must be ASCII characters " ))
117- oq, cq = openquotechar != = nothing ? (openquotechar % UInt8, closequotechar % UInt8) : (quotechar % UInt8, quotechar % UInt8)
118- e = escapechar % UInt8
119- opts = Options (tup (delim), oq, cq, e, tup (newline), decimal % UInt8, dateformat, quotestrings, tup (missingstring), transform, bom)
124+ bufsize:: Int = 2 ^ 22 ,
125+ kw... )
126+ opts = Options (; kw... )
120127 source = Tables. rows (table)
121128 sch = Tables. schema (source)
122129 return RowWriter (source, sch, opts, Vector {UInt8} (undef, bufsize), header, writeheader)
@@ -151,34 +158,18 @@ end
151158
152159write (file; kwargs... ) = x-> write (file, x; kwargs... )
153160function write (file, itr;
154- delim:: Union{Char, String} = ' ,' ,
155- quotechar:: Char = ' "' ,
156- openquotechar:: Union{Char, Nothing} = nothing ,
157- closequotechar:: Union{Char, Nothing} = nothing ,
158- escapechar:: Char = ' "' ,
159- newline:: Union{Char, String} = ' \n ' ,
160- decimal:: Char = ' .' ,
161- dateformat= nothing ,
162- quotestrings:: Bool = false ,
163- missingstring:: AbstractString = " " ,
164- transform:: Function = _identity,
165- bom:: Bool = false ,
166161 append:: Bool = false ,
167162 compress:: Bool = false ,
168163 writeheader= nothing ,
169164 partition:: Bool = false ,
170- kwargs... )
171- checkvaliddelim (delim)
165+ kw... )
172166 if writeheader != = nothing
173167 Base. depwarn (" `writeheader=$writeheader ` is deprecated in favor of `header=$writeheader `" , :write )
174168 header = writeheader
175169 else
176170 header = ! append
177171 end
178- (isascii (something (openquotechar, quotechar)) && isascii (something (closequotechar, quotechar)) && isascii (escapechar)) || throw (ArgumentError (" quote and escape characters must be ASCII characters " ))
179- oq, cq = openquotechar != = nothing ? (openquotechar % UInt8, closequotechar % UInt8) : (quotechar % UInt8, quotechar % UInt8)
180- e = escapechar % UInt8
181- opts = Options (tup (delim), oq, cq, e, tup (newline), decimal % UInt8, dateformat, quotestrings, tup (missingstring), transform, bom)
172+ opts = Options (; kw... )
182173 if partition
183174 if file isa IO
184175 throw (ArgumentError (" must pass single file name as a String, or iterable of filenames or IO arguments" ))
@@ -190,32 +181,29 @@ function write(file, itr;
190181 if file isa String
191182 push! (outfiles, string (file, " _$i " ))
192183 end
193- write (outfiles[i], part; delim= delim, quotechar= quotechar, openquotechar= openquotechar, closequotechar= closequotechar, escapechar= escapechar, newline= newline,
194- decimal= decimal, dateformat= dateformat, quotestrings= quotestrings, missingstring= missingstring, transform= transform, bom= bom, append= append, compress= compress,
195- writeheader= writeheader, partition= false , kwargs... )
184+ write (outfiles[i], part; append= append, compress= compress, writeheader= writeheader, partition= false , kw... )
196185 end
197186 else
198187 if file isa String
199188 push! (outfiles, string (file, " _$i " ))
200189 end
201- write (outfiles[i], part; delim= delim, quotechar= quotechar, openquotechar= openquotechar, closequotechar= closequotechar, escapechar= escapechar, newline= newline,
202- decimal= decimal, dateformat= dateformat, quotestrings= quotestrings, missingstring= missingstring, transform= transform, bom= bom, append= append, compress= compress,
203- writeheader= writeheader, partition= false , kwargs... )
190+ write (outfiles[i], part; append= append, compress= compress, writeheader= writeheader, partition= false , kw... )
204191 end
205192 end
206193 return outfiles
207194 else
208195 rows = Tables. rows (itr)
209196 sch = Tables. schema (rows)
210- return write (sch, rows, file, opts; append= append, compress= compress, header= header, kwargs ... )
197+ return write (sch, rows, file, opts; append= append, compress= compress, header= header, kw ... )
211198 end
212199end
213200
214201function write (sch:: Tables.Schema , rows, file, opts;
215202 append:: Bool = false ,
216203 compress:: Bool = false ,
217204 header:: Union{Bool, Vector} = String[],
218- bufsize:: Int = 2 ^ 22
205+ bufsize:: Int = 2 ^ 22 ,
206+ kw...
219207 )
220208 colnames = ! (header isa Vector) || isempty (header) ? sch. names : header
221209 cols = length (colnames)
@@ -244,7 +232,8 @@ function write(::Nothing, rows, file, opts;
244232 append:: Bool = false ,
245233 compress:: Bool = false ,
246234 header:: Union{Bool, Vector} = String[],
247- bufsize:: Int = 2 ^ 22
235+ bufsize:: Int = 2 ^ 22 ,
236+ kw...
248237 )
249238 len = bufsize
250239 buf = Vector {UInt8} (undef, len)
@@ -374,6 +363,37 @@ function writerow(buf, pos, len, io, sch, row, cols, opts)
374363 return
375364end
376365
366+ function writerow (io:: IO , row; opts:: Union{Options, Nothing} = nothing , bufsize:: Int = 2 ^ 22 , buf= Vector {UInt8} (undef, bufsize), len= bufsize, kw... )
367+ if opts === nothing
368+ opts = Options (; kw... )
369+ end
370+ nms = Tables. columnnames (row)
371+ pos = 1
372+ for i = 1 : length (nms)
373+ val = opts. transform (i, Tables. getcolumn (row, i))
374+ val === nothing && nothingerror (col)
375+ pos = writecell (buf, pos, len, io, val, opts)
376+ pos = writedelimnewline (buf, pos, len, io, ifelse (i == length (nms), opts. newline, opts. delim))
377+ end
378+ Base. write (io, resize! (buf, pos - 1 ))
379+ end
380+
381+ function writerow (row; opts:: Union{Options, Nothing} = nothing , bufsize:: Int = 2 ^ 22 , buf= Vector {UInt8} (undef, bufsize), len= bufsize, kw... )
382+ if opts === nothing
383+ opts = Options (; kw... )
384+ end
385+ io = DummyIO ()
386+ nms = Tables. columnnames (row)
387+ pos = 1
388+ for i = 1 : length (nms)
389+ val = opts. transform (i, Tables. getcolumn (row, i))
390+ val === nothing && nothingerror (col)
391+ pos = writecell (buf, pos, len, io, val, opts)
392+ pos = writedelimnewline (buf, pos, len, io, ifelse (i == length (nms), opts. newline, opts. delim))
393+ end
394+ return unsafe_string (pointer (buf), pos - 1 )
395+ end
396+
377397function writecell (buf, pos, len, io, :: Missing , opts)
378398 str = opts. missingstring
379399 t = tlen (str)
0 commit comments