3
3
module DataFmt
4
4
5
5
importall Base
6
- import Base: _default_delims
6
+ import Base: _default_delims, tryparse_internal
7
7
8
8
export countlines, readdlm, readcsv, writedlm, writecsv
9
9
@@ -137,15 +137,14 @@ type DLMStore{T,S<:ByteString} <: DLMHandler
137
137
sbuff:: S
138
138
auto:: Bool
139
139
eol:: Char
140
- tmp64:: Array{Float64,1}
141
140
end
142
141
143
142
function DLMStore {T,S<:ByteString} (:: Type{T} , dims:: NTuple{2,Integer} , has_header:: Bool , sbuff:: S , auto:: Bool , eol:: Char )
144
143
(nrows,ncols) = dims
145
144
nrows <= 0 && throw (ArgumentError (" number of rows in dims must be > 0, got $nrows " ))
146
145
ncols <= 0 && throw (ArgumentError (" number of columns in dims must be > 0, got $ncols " ))
147
146
hdr_offset = has_header ? 1 : 0
148
- DLMStore {T,S} (fill (SubString (sbuff,1 ,0 ), 1 , ncols), Array (T, nrows- hdr_offset, ncols), nrows, ncols, 0 , 0 , hdr_offset, sbuff, auto, eol, Array (Float64, 1 ) )
147
+ DLMStore {T,S} (fill (SubString (sbuff,1 ,0 ), 1 , ncols), Array (T, nrows- hdr_offset, ncols), nrows, ncols, 0 , 0 , hdr_offset, sbuff, auto, eol)
149
148
end
150
149
151
150
_chrinstr (sbuff:: ByteString , chr:: UInt8 , startpos:: Int , endpos:: Int ) = (endpos >= startpos) && (C_NULL != ccall (:memchr , Ptr{UInt8}, (Ptr{UInt8}, Int32, Csize_t), pointer (sbuff. data)+ startpos- 1 , chr, endpos- startpos+ 1 ))
@@ -158,7 +157,6 @@ function store_cell{T,S<:ByteString}(dlmstore::DLMStore{T,S}, row::Int, col::Int
158
157
lastrow = dlmstore. lastrow
159
158
cells:: Array{T,2} = dlmstore. data
160
159
sbuff:: S = dlmstore. sbuff
161
- tmp64 = dlmstore. tmp64
162
160
163
161
endpos = prevind (sbuff, nextind (sbuff,endpos))
164
162
(endpos > 0 ) && (' \n ' == dlmstore. eol) && (' \r ' == Char (sbuff[endpos])) && (endpos = prevind (sbuff, endpos))
@@ -189,9 +187,9 @@ function store_cell{T,S<:ByteString}(dlmstore::DLMStore{T,S}, row::Int, col::Int
189
187
# fill data
190
188
if quoted && _chrinstr (sbuff, UInt8 (' "' ), startpos, endpos)
191
189
unescaped = replace (SubString (sbuff,startpos,endpos), r" \"\" " , " \" " )
192
- fail = colval (unescaped, 1 , length (unescaped), cells, drow, col, tmp64 )
190
+ fail = colval (unescaped, 1 , length (unescaped), cells, drow, col)
193
191
else
194
- fail = colval (sbuff, startpos, endpos, cells, drow, col, tmp64 )
192
+ fail = colval (sbuff, startpos, endpos, cells, drow, col)
195
193
end
196
194
if fail
197
195
sval = SubString (sbuff,startpos,endpos)
@@ -204,9 +202,9 @@ function store_cell{T,S<:ByteString}(dlmstore::DLMStore{T,S}, row::Int, col::Int
204
202
# fill header
205
203
if quoted && _chrinstr (sbuff, UInt8 (' "' ), startpos, endpos)
206
204
unescaped = replace (SubString (sbuff,startpos,endpos), r" \"\" " , " \" " )
207
- colval (unescaped, 1 , length (unescaped), dlmstore. hdr, 1 , col, tmp64 )
205
+ colval (unescaped, 1 , length (unescaped), dlmstore. hdr, 1 , col)
208
206
else
209
- colval (sbuff, startpos,endpos, dlmstore. hdr, 1 , col, tmp64 )
207
+ colval (sbuff, startpos,endpos, dlmstore. hdr, 1 , col)
210
208
end
211
209
end
212
210
@@ -304,6 +302,8 @@ function dlm_fill(T::DataType, offarr::Vector{Vector{Int}}, dims::NTuple{2,Integ
304
302
idx = 1
305
303
offidx = 1
306
304
offsets = offarr[1 ]
305
+ row = 0
306
+ col = 0
307
307
try
308
308
dh = DLMStore (T, dims, has_header, sbuff, auto, eol)
309
309
while idx <= length (offsets)
@@ -320,40 +320,52 @@ function dlm_fill(T::DataType, offarr::Vector{Vector{Int}}, dims::NTuple{2,Integ
320
320
return result (dh)
321
321
catch ex
322
322
isa (ex, TypeError) && (ex. func == :store_cell ) && (return dlm_fill (ex. expected, offarr, dims, has_header, sbuff, auto, eol))
323
- rethrow (ex )
323
+ error ( " at row $row , column $col : $ex " )
324
324
end
325
325
end
326
326
327
-
328
- function colval {T<:Bool, S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{T,2} , row:: Int , col:: Int , tmp64:: Array{Float64,1} )
329
- len = endpos- startpos+ 1
330
- if (len == 4 ) && (0 == ccall (:memcmp , Int32, (Ptr{UInt8}, Ptr{UInt8}, UInt), pointer (sbuff)+ startpos- 1 , pointer (" true" ), 4 ))
331
- cells[row,col] = true
332
- return false
333
- elseif (len == 5 ) && (0 == ccall (:memcmp , Int32, (Ptr{UInt8}, Ptr{UInt8}, UInt), pointer (sbuff)+ startpos- 1 , pointer (" false" ), 5 ))
334
- cells[row,col] = false
335
- return false
336
- end
337
- true
327
+ function colval {S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{Bool,2} , row:: Int , col:: Int )
328
+ n = tryparse_internal (Bool, sbuff, startpos, endpos, false )
329
+ isnull (n) || (cells[row,col] = get (n))
330
+ isnull (n)
338
331
end
339
- function colval {T<:Number, S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{T,2} , row:: Int , col:: Int , tmp64:: Array{Float64,1} )
340
- if 0 == ccall (:jl_substrtod , Int32, (Ptr{UInt8},Csize_t,Cint,Ptr{Float64}), sbuff, startpos- 1 , endpos- startpos+ 1 , tmp64)
341
- cells[row,col] = tmp64[1 ]
342
- return false
343
- end
344
- true
332
+ function colval {T<:Integer, S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{T,2} , row:: Int , col:: Int )
333
+ n = tryparse_internal (T, sbuff, startpos, endpos, 0 , false )
334
+ isnull (n) || (cells[row,col] = get (n))
335
+ isnull (n)
345
336
end
346
- colval {T<:AbstractString, S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{T,2} , row:: Int , col:: Int , tmp64:: Array{Float64,1} ) = ((cells[row,col] = SubString (sbuff,startpos,endpos)); false )
347
- function colval {S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{Any,2} , row:: Int , col:: Int , tmp64:: Array{Float64,1} )
348
- if 0 == ccall (:jl_substrtod , Int32, (Ptr{UInt8},Csize_t,Cint,Ptr{Float64}), sbuff, startpos- 1 , endpos- startpos+ 1 , tmp64)
349
- cells[row,col] = tmp64[1 ]
350
- else
351
- cells[row,col] = SubString (sbuff, startpos, endpos)
337
+ function colval {S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{Float64,2} , row:: Int , col:: Int )
338
+ n = ccall (:jl_try_substrtod , Nullable{Float64}, (Ptr{UInt8},Csize_t,Cint), sbuff, startpos- 1 , endpos- startpos+ 1 )
339
+ isnull (n) || (cells[row,col] = get (n))
340
+ isnull (n)
341
+ end
342
+ function colval {S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{Float32,2} , row:: Int , col:: Int )
343
+ n = ccall (:jl_try_substrtof , Nullable{Float32}, (Ptr{UInt8},Csize_t,Cint), sbuff, startpos- 1 , endpos- startpos+ 1 )
344
+ isnull (n) || (cells[row,col] = get (n))
345
+ isnull (n)
346
+ end
347
+ colval {T<:AbstractString, S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{T,2} , row:: Int , col:: Int ) = ((cells[row,col] = SubString (sbuff,startpos,endpos)); false )
348
+ function colval {S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{Any,2} , row:: Int , col:: Int )
349
+ # if array is of Any type, attempt parsing only the most common types: Int, Bool, Float64 and fallback to SubString
350
+ len = endpos- startpos+ 1
351
+ if len > 0
352
+ # check Inteter
353
+ ni64 = tryparse_internal (Int, sbuff, startpos, endpos, 0 , false )
354
+ isnull (ni64) || (cells[row,col] = get (ni64); return false )
355
+
356
+ # check Bool
357
+ nb = tryparse_internal (Bool, sbuff, startpos, endpos, false )
358
+ isnull (nb) || (cells[row,col] = get (nb); return false )
359
+
360
+ # check float64
361
+ nf64 = ccall (:jl_try_substrtod , Nullable{Float64}, (Ptr{UInt8},Csize_t,Cint), sbuff, startpos- 1 , endpos- startpos+ 1 )
362
+ isnull (nf64) || (cells[row,col] = get (nf64); return false )
352
363
end
364
+ cells[row,col] = SubString (sbuff, startpos, endpos)
353
365
false
354
366
end
355
- colval {T<:Char, S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{T,2} , row:: Int , col:: Int , tmp64 :: Array{Float64,1} ) = ((startpos== endpos) ? ((cells[row,col] = next (sbuff,startpos)[1 ]); false ) : true )
356
- colval {S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array , row:: Int , col:: Int , tmp64 :: Array{Float64,1} ) = true
367
+ colval {T<:Char, S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array{T,2} , row:: Int , col:: Int ) = ((startpos== endpos) ? ((cells[row,col] = next (sbuff,startpos)[1 ]); false ) : true )
368
+ colval {S<:ByteString} (sbuff:: S , startpos:: Int , endpos:: Int , cells:: Array , row:: Int , col:: Int ) = true
357
369
358
370
dlm_parse (s:: ASCIIString , eol:: Char , dlm:: Char , qchar:: Char , cchar:: Char , ign_adj_dlm:: Bool , allow_quote:: Bool , allow_comments:: Bool , skipstart:: Int , skipblanks:: Bool , dh:: DLMHandler ) = begin
359
371
dlm_parse (s. data, UInt32 (eol)% UInt8, UInt32 (dlm)% UInt8, UInt32 (qchar)% UInt8, UInt32 (cchar)% UInt8,
0 commit comments