| 372 | } |
| 373 | |
| 374 | Status TF_TensorToTensor(const TF_Tensor* src, Tensor* dst) { |
| 375 | if (src->tensor.dtype() == DT_RESOURCE) { |
| 376 | if (src->tensor.dims() != 0) { |
| 377 | return InvalidArgument( |
| 378 | "Malformed TF_RESOURCE tensor: expected a scalar, got a tensor with " |
| 379 | "shape ", |
| 380 | src->tensor.shape().DebugString()); |
| 381 | } |
| 382 | *dst = Tensor(tensorflow::DT_RESOURCE, src->tensor.shape()); |
| 383 | if (!dst->scalar<tensorflow::ResourceHandle>()().ParseFromString( |
| 384 | string(static_cast<const char*>(TF_TensorData(src)), |
| 385 | TF_TensorByteSize(src)))) { |
| 386 | return InvalidArgument( |
| 387 | "Malformed TF_RESOUCE tensor: unable to parse resource handle"); |
| 388 | } |
| 389 | return Status::OK(); |
| 390 | } |
| 391 | if (src->tensor.dtype() != DT_STRING) { |
| 392 | *dst = src->tensor; |
| 393 | return Status::OK(); |
| 394 | } |
| 395 | // TF_STRING tensors require copying since Tensor class expects a sequence of |
| 396 | // string objects. |
| 397 | const tensorflow::int64 num_elements = src->tensor.NumElements(); |
| 398 | const char* input = reinterpret_cast<const char*>(TF_TensorData(src)); |
| 399 | const size_t src_size = TF_TensorByteSize(src); |
| 400 | if (static_cast<tensorflow::int64>(src_size / sizeof(tensorflow::uint64)) < |
| 401 | num_elements) { |
| 402 | return InvalidArgument( |
| 403 | "Malformed TF_STRING tensor; too short to hold number of elements"); |
| 404 | } |
| 405 | const char* data_start = input + sizeof(tensorflow::uint64) * num_elements; |
| 406 | const char* limit = input + src_size; |
| 407 | |
| 408 | *dst = Tensor(src->tensor.dtype(), src->tensor.shape()); |
| 409 | auto dstarray = dst->flat<tstring>(); |
| 410 | for (tensorflow::int64 i = 0; i < num_elements; ++i) { |
| 411 | tensorflow::uint64 offset = |
| 412 | reinterpret_cast<const tensorflow::uint64*>(input)[i]; |
| 413 | if (static_cast<ptrdiff_t>(offset) >= (limit - data_start)) { |
| 414 | return InvalidArgument("Malformed TF_STRING tensor; element ", i, |
| 415 | " out of range"); |
| 416 | } |
| 417 | size_t len; |
| 418 | const char* p; |
| 419 | const char* srcp = data_start + offset; |
| 420 | Status status = TF_StringDecode_Impl(srcp, limit - srcp, &p, &len); |
| 421 | if (!status.ok()) return status; |
| 422 | dstarray(i).assign(p, len); |
| 423 | } |
| 424 | return Status::OK(); |
| 425 | } |
| 426 | |
| 427 | } // namespace tensorflow |
| 428 | |