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

Code before:
    return header_length;
  }

  Status WriteHeader() {
    // Only called once, as part of initialization
    RETURN_NOT_OK(data_buffer_->Resize(CalculateHeaderSize(options_.quoting_header),
                                       /*shrink_to_fit=*/false));
    char* next = reinterpret_cast<char*>(data_buffer_->mutable_data());
    for (int col = 0; col < schema_->num_fields(); ++col) {
      const std::string& col_name = schema_->field(col)->name();
      switch (options_.quoting_header) {
        case QuotingStyle::None:
          if (StopAtStructuralChar(reinterpret_cast<const uint8_t*>(col_name.c_str()),
                                   col_name.length(), options_.delimiter) !=
              static_cast<int64_t>(col_name.length())) {
            return Status::Invalid(
                "CSV header may not contain structural characters if quoting style is "
                "\"None\". See RFC4180. Invalid value: ",
                col_name);
          }
          memcpy(next, col_name.data(), col_name.size());
          next += col_name.size();
          break;
        // The behavior of the Needed quoting_style in CSV data depends on the data type.
        // And it is always quoted when the data type is binary. To avoid semantic
        // differences, the behavior of Need and AllValid should be consistent.
        case QuotingStyle::Needed:
        case QuotingStyle::AllValid:
          *next++ = '"';
          next = Escape(schema_->field(col)->name(), next);
          *next++ = '"';
          break;
      }
      if (col != schema_->num_fields() - 1) {
        *next++ = options_.delimiter;
      }
    }
    memcpy(next, options_.eol.data(), options_.eol.size());
    next += options_.eol.size();
    DCHECK_EQ(reinterpret_cast<uint8_t*>(next),
              data_buffer_->data() + data_buffer_->size());
    return sink_->Write(data_buffer_);
  }

  Status TranslateMinimalBatch(const RecordBatch& batch) {
    if (batch.num_rows() == 0) {
      return Status::OK();
    }
    offsets_.resize(batch.num_rows());
    std::fill(offsets_.begin(), offsets_.end(), 0);


Review comment (suggestion):
```suggestion
        // QuotingStyle::Needed is defined as always quoting string/binary data,
        // regardless of whether it contains structural chars.
        // We use consistent semantics for header names, which are strings.
```

Code after:
        break;
    }
    return header_length;
  }

  Status WriteHeader() {
    // Only called once, as part of initialization
    RETURN_NOT_OK(data_buffer_->Resize(CalculateHeaderSize(options_.quoting_header),
                                       /*shrink_to_fit=*/false));
    char* next = reinterpret_cast<char*>(data_buffer_->mutable_data());
    for (int col = 0; col < schema_->num_fields(); ++col) {
      const std::string& col_name = schema_->field(col)->name();
      switch (options_.quoting_header) {
        case QuotingStyle::None:
          if (StopAtStructuralChar(reinterpret_cast<const uint8_t*>(col_name.c_str()),
                                   col_name.length(), options_.delimiter) !=
              static_cast<int64_t>(col_name.length())) {
            return Status::Invalid(
                "CSV header may not contain structural characters if quoting style is "
                "\"None\". See RFC4180. Invalid value: ",
                col_name);
          }
          memcpy(next, col_name.data(), col_name.size());
          next += col_name.size();
          break;
        case QuotingStyle::Needed:
        case QuotingStyle::AllValid:
          // QuotingStyle::Needed is defined as always quoting string/binary data,
          // regardless of whether it contains structural chars.
          // We use consistent semantics for header names, which are strings.
          *next++ = '"';
          next = Escape(schema_->field(col)->name(), next);
          *next++ = '"';
          break;
      }
      if (col != schema_->num_fields() - 1) {
        *next++ = options_.delimiter;
      }
    }
    memcpy(next, options_.eol.data(), options_.eol.size());
    next += options_.eol.size();
    DCHECK_EQ(reinterpret_cast<uint8_t*>(next),
              data_buffer_->data() + data_buffer_->size());
    return sink_->Write(data_buffer_);
  }

  Status TranslateMinimalBatch(const RecordBatch& batch) {
    if (batch.num_rows() == 0) {
      return Status::OK();
    }
    offsets_.resize(batch.num_rows());