MCPcopy Create free account
hub / github.com/dolthub/doltgresql / parseQuotedField

Method parseQuotedField

core/dataloader/csvreader.go:294–364  ·  view source on GitHub ↗
(rs *recordState)

Source from the content-addressed store, hash-verified

292}
293
294func (csvr *csvReader) parseQuotedField(rs *recordState) (kontinue bool, err error) {
295 const quoteLen = len(`"`)
296 dl := len(csvr.delim)
297 recordStartLine := csvr.numLine
298 // full copy needed here because we append rs.line to fullField, and this can result in buffer corruption in
299 // some cases (namely when windows line endings are present)
300 fullField := make([]byte, len(rs.line))
301 copy(fullField, rs.line)
302
303 // Quoted string field
304 rs.line = rs.line[quoteLen:]
305 for {
306 i := bytes.IndexByte(rs.line, '"')
307 if i >= 0 {
308 // Hit next quote.
309 rs.recordBuffer = append(rs.recordBuffer, rs.line[:i]...)
310 rs.line = rs.line[i+quoteLen:]
311
312 atDelimiter := len(rs.line) >= dl && bytes.Equal(rs.line[:dl], csvr.delim)
313 nextRune, _ := utf8.DecodeRune(rs.line)
314
315 switch {
316 case atDelimiter:
317 // `"<delimiter>` sequence (end of field).
318 rs.line = rs.line[dl:]
319 rs.fieldIndexes = append(rs.fieldIndexes, len(rs.recordBuffer))
320 return true, err
321 case nextRune == '"':
322 // `""` sequence (append quote).
323 rs.recordBuffer = append(rs.recordBuffer, '"')
324 rs.line = rs.line[quoteLen:]
325 case lengthNL(rs.line) == len(rs.line):
326 // `"\n` sequence (end of line).
327 rs.fieldIndexes = append(rs.fieldIndexes, len(rs.recordBuffer))
328 return false, err
329 default:
330 // `"*` sequence (invalid non-escaped quote).
331 col := utf8.RuneCount(fullField[:len(fullField)-len(rs.line)-quoteLen])
332 err = &csv.ParseError{StartLine: recordStartLine, Line: csvr.numLine, Column: col, Err: csv.ErrQuote}
333 return false, err
334 }
335 } else if len(rs.line) > 0 {
336 // Hit end of line (copy all data so far).
337 rs.recordBuffer = append(rs.recordBuffer, rs.line...)
338 if err != nil {
339 return false, err
340 }
341
342 rs.line, err = csvr.readLine()
343 rs.rawData = append(rs.rawData, rs.line...)
344 if err == io.EOF {
345 err = nil
346 }
347 // If we get a partialLineError, populate the partialLine field with the full record data
348 // since quoted fields can span multiple lines, otherwise we wouldn't capture the initial
349 // lines of this record.
350 if ple, ok := err.(*partialLineError); ok {
351 ple.partialLine = string(rs.rawData)

Callers 1

csvReadRecordsMethod · 0.95

Calls 3

readLineMethod · 0.95
lengthNLFunction · 0.85
EqualMethod · 0.45

Tested by

no test coverage detected