MCPcopy Create free account
hub / github.com/apache/arrow / operator()

Method operator()

r/src/io.cpp:495–593  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

493 n_pending_(0) {}
494
495 arrow::Result<std::shared_ptr<arrow::Buffer>> operator()(
496 const std::shared_ptr<arrow::Buffer>& src) {
497 // A pre-allocation factor to account for possible data growth when
498 // converting to UTF-8.
499 constexpr double kOversizeFactor = 1.2;
500
501 arrow::BufferBuilder builder;
502 const int64_t initial_size = static_cast<int64_t>(src->size() * kOversizeFactor);
503 RETURN_NOT_OK(builder.Reserve(initial_size));
504
505 int64_t out_bytes_left = builder.capacity();
506 uint8_t* out_buf = builder.mutable_data();
507
508 int64_t in_bytes_left;
509 const uint8_t* in_buf;
510 int64_t n_src_bytes_in_pending = 0;
511
512 // There may be a few left over bytes from the last call to iconv.
513 // Process these first using the internal buffer (with as many bytes
514 // as possible added from src) as the source. This may also result in
515 // a partial character left over but will always get us into the src buffer.
516 if (n_pending_ > 0) {
517 n_src_bytes_in_pending =
518 std::min<int64_t>(sizeof(pending_) - n_pending_, src->size());
519 memcpy(pending_ + n_pending_, src->data(), n_src_bytes_in_pending);
520 in_buf = pending_;
521 in_bytes_left = n_pending_ + n_src_bytes_in_pending;
522
523 iconv_->iconv(&in_buf, &in_bytes_left, &out_buf, &out_bytes_left);
524
525 // Rather than check the error return code (which is often returned
526 // in the case of a partial character at the end of the pending_
527 // buffer), check that we have read enough characters to get into
528 // `src` (after which the loop below will error for invalid characters).
529 int64_t bytes_read_in = in_buf - pending_;
530 if (bytes_read_in < n_pending_) {
531 return StatusInvalidInput();
532 }
533
534 int64_t bytes_read_out = out_buf - builder.mutable_data();
535 builder.UnsafeAdvance(bytes_read_out);
536
537 int64_t chars_read_in = n_pending_ + n_src_bytes_in_pending - in_bytes_left;
538 in_buf = src->data() + chars_read_in - n_pending_;
539 in_bytes_left = src->size() + n_pending_ - chars_read_in;
540 } else {
541 in_buf = src->data();
542 in_bytes_left = src->size();
543 }
544
545 // Try to call iconv() as many times as we need, potentially enlarging
546 // the output buffer as needed. When zero bytes are appended, the loop
547 // will either error (if there are more than 4 bytes left) or copy the
548 // bytes to pending_ and wait for more input. We use 4 bytes because
549 // this is the maximum number of bytes per complete character in UTF-8,
550 // UTF-16, and UTF-32.
551 while (in_bytes_left > 0) {
552 // Make enough place in the output to hopefully consume all of the input.

Callers

nothing calls this directly

Calls 9

iconvMethod · 0.80
sizeMethod · 0.45
ReserveMethod · 0.45
capacityMethod · 0.45
mutable_dataMethod · 0.45
dataMethod · 0.45
UnsafeAdvanceMethod · 0.45
lengthMethod · 0.45
FinishMethod · 0.45

Tested by

no test coverage detected