* Encodes Unicode codepoints into the desired string representation. * * We lose a dimension while encoding, since a series of integer codepoints is * encoded into a single string. * * This accepts two input tensors: a rank 1 tensor of code point values and * a single rank 1 tensor of splits which determine where each string begins * and ends from the provided code points.
| 525 | * and ends from the provided code points. |
| 526 | */ |
| 527 | void Compute(OpKernelContext* context) override { |
| 528 | // Get inputs |
| 529 | const Tensor& input_tensor = context->input(0); |
| 530 | const auto input_tensor_flat = input_tensor.flat<int32>(); |
| 531 | const Tensor& input_splits = context->input(1); |
| 532 | const auto input_splits_flat = input_splits.flat<SPLITS_TYPE>(); |
| 533 | |
| 534 | OP_REQUIRES( |
| 535 | context, input_splits.NumElements() > 0, |
| 536 | errors::InvalidArgument("Input_splits should contain elements, but " |
| 537 | "given input_values has 0 elements")); |
| 538 | // Since we limit to a 2-D input (flat_values of rank 1 and a single splits |
| 539 | // tensor), our output dimension will be 1 with it's size equal to the |
| 540 | // number of splits (outer dimension or ragged tensor). |
| 541 | TensorShape output_shape({input_splits.dim_size(0) - 1}); |
| 542 | Tensor* output_tensor; |
| 543 | OP_REQUIRES_OK(context, context->allocate_output("output", output_shape, |
| 544 | &output_tensor)); |
| 545 | auto output_tensor_flat = output_tensor->flat<tstring>(); |
| 546 | |
| 547 | // Use a single index over the flattened input values tensor. |
| 548 | int idx = 0; |
| 549 | // Loop through our split dimension to create a new string at each split. |
| 550 | for (int i = 1; i < input_splits_flat.size(); ++i) { |
| 551 | icu::UnicodeString unicode_string; |
| 552 | icu::UnicodeStringAppendable appendable_unicode_string(unicode_string); |
| 553 | for (; idx < input_splits_flat(i); ++idx) { |
| 554 | int32 code_point = input_tensor_flat(idx); |
| 555 | // Check for invalid code point |
| 556 | if (code_point > UCHAR_MAX_VALUE || code_point < UCHAR_MIN_VALUE) { |
| 557 | if (error_options_.error_on_malformatting) { |
| 558 | context->CtxFailure(errors::InvalidArgument( |
| 559 | "Code point value out of valid Unicode range.")); |
| 560 | return; |
| 561 | } else if (!error_options_.elide_replacement) { |
| 562 | code_point = error_options_.subst; |
| 563 | } |
| 564 | } |
| 565 | appendable_unicode_string.appendCodePoint(code_point); |
| 566 | } |
| 567 | // Encode our string and save in the output. |
| 568 | string result; |
| 569 | Encode(encoding_, unicode_string, &result); |
| 570 | output_tensor_flat(i - 1) = result; |
| 571 | } |
| 572 | } |
| 573 | |
| 574 | private: |
| 575 | UnicodeEncoding encoding_; |
nothing calls this directly
no test coverage detected