Repository: apache/arrow
File: cpp/src/arrow/csv/writer.cc (C++)

Code before:
 protected:
  virtual Status UpdateRowLengths(int64_t* row_lengths) = 0;
  // It must be a `StringArray` or `LargeStringArray`.
  std::shared_ptr<Array> array_;
  const std::string end_chars_;
  std::shared_ptr<Buffer> null_string_;

 private:
  MemoryPool* const pool_;
};

// Copies the contents of s to out properly escaping any necessary characters.
// Returns the position next to last copied character.
char* Escape(std::string_view s, char* out) {
  for (const char c : s) {
    *out++ = c;
    if (c == '"') {
      *out++ = '"';
    }
  }
  return out;
}

int64_t StopAtStructuralChar(const uint8_t* data, const int64_t buffer_size,
                             const char delimiter) {
  int64_t offset = 0;
#if defined(ARROW_HAVE_SSE4_2) || defined(ARROW_HAVE_NEON)
  // _mm_cmpistrc gives slightly better performance than the naive approach,
  // probably doesn't deserve the effort
  using simd_batch = xsimd::make_sized_batch_t<uint8_t, 16>;
  while ((offset + 16) <= buffer_size) {
    const auto v = simd_batch::load_unaligned(data + offset);
    if (xsimd::any((v == '\n') | (v == '\r') | (v == '"') | (v == delimiter))) {
      break;
    }
    offset += 16;
  }
#endif
  while (offset < buffer_size) {
    // error happened or remaining bytes to check
    const char c = static_cast<char>(data[offset]);
    if (c == '\n' || c == '\r' || c == '"' || c == delimiter) {
      break;
    }
    ++offset;
  }
  return offset;
}

// Populator used for non-string/binary types, or when unquoted strings/binary types are
// desired. It assumes the strings in the casted array do not require quoting or escaping.

Review comment (suggestion):
```suggestion
// Return the index of the first structural char in the input. A structural char
// is a character that needs quoting and/or escaping.
int64_t StopAtStructuralChar(const uint8_t* data, const int64_t buffer_size,
```

Code after:
 protected:
  virtual Status UpdateRowLengths(int64_t* row_lengths) = 0;
  // It must be a `StringArray` or `LargeStringArray`.
  std::shared_ptr<Array> array_;
  const std::string end_chars_;
  std::shared_ptr<Buffer> null_string_;

 private:
  MemoryPool* const pool_;
};

// Copies the contents of s to out properly escaping any necessary characters.
// Returns the position next to last copied character.
char* Escape(std::string_view s, char* out) {
  for (const char c : s) {
    *out++ = c;
    if (c == '"') {
      *out++ = '"';
    }
  }
  return out;
}

// Return the index of the first structural char in the input. A structural char
// is a character that needs quoting and/or escaping.
int64_t StopAtStructuralChar(const uint8_t* data, const int64_t buffer_size,
                             const char delimiter) {
  int64_t offset = 0;
#if defined(ARROW_HAVE_SSE4_2) || defined(ARROW_HAVE_NEON)
  // _mm_cmpistrc gives slightly better performance than the naive approach,
  // probably doesn't deserve the effort
  using simd_batch = xsimd::make_sized_batch_t<uint8_t, 16>;
  while ((offset + 16) <= buffer_size) {
    const auto v = simd_batch::load_unaligned(data + offset);
    if (xsimd::any((v == '\n') | (v == '\r') | (v == '"') | (v == delimiter))) {
      break;
    }
    offset += 16;
  }
#endif
  while (offset < buffer_size) {
    // error happened or remaining bytes to check
    const char c = static_cast<char>(data[offset]);
    if (c == '\n' || c == '\r' || c == '"' || c == delimiter) {
      break;
    }
    ++offset;
  }
  return offset;
}