-
Notifications
You must be signed in to change notification settings - Fork 125
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #866 from khanhlvg:ios-cpp-common-utils-fixes
PiperOrigin-RevId: 467451277
- Loading branch information
Showing
11 changed files
with
200 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
/* Copyright 2022 The TensorFlow Authors. All Rights Reserved. | ||
Licensed under the Apache License, Version 2.0 (the "License"); | ||
you may not use this file except in compliance with the License. | ||
You may obtain a copy of the License at | ||
http://www.apache.org/licenses/LICENSE-2.0 | ||
Unless required by applicable law or agreed to in writing, software | ||
distributed under the License is distributed on an "AS IS" BASIS, | ||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
See the License for the specific language governing permissions and | ||
limitations under the License. | ||
==============================================================================*/ | ||
#import <Foundation/Foundation.h> | ||
|
||
#import "tensorflow_lite_support/ios/sources/TFLCommonUtils.h" | ||
|
||
#include "absl/status/status.h" // from @com_google_absl | ||
|
||
NS_ASSUME_NONNULL_BEGIN | ||
|
||
/** Helper utility for the all tasks which encapsulates common functionality of | ||
* the iOS task library backed by C++ APIs. */ | ||
@interface TFLCommonCppUtils : TFLCommonUtils | ||
|
||
/** | ||
* Converts an absl status to an NSError. | ||
* | ||
* @param status absl status. | ||
* @param error Pointer to the memory location where the created error should be saved. If `nil`, | ||
* no error will be saved. | ||
*/ | ||
+ (BOOL)checkCppError:(const absl::Status &)status toError:(NSError **)error; | ||
|
||
@end | ||
|
||
NS_ASSUME_NONNULL_END |
107 changes: 107 additions & 0 deletions
107
tensorflow_lite_support/ios/sources/TFLCommonCppUtils.mm
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,107 @@ | ||
// Copyright 2022 The TensorFlow Authors. All Rights Reserved. | ||
// | ||
// Licensed under the Apache License, Version 2.0 (the "License"); | ||
// you may not use this file except in compliance with the License. | ||
// You may obtain a copy of the License at | ||
// | ||
// http://www.apache.org/licenses/LICENSE-2.0 | ||
// | ||
// Unless required by applicable law or agreed to in writing, software | ||
// distributed under the License is distributed on an "AS IS" BASIS, | ||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
// See the License for the specific language governing permissions and | ||
// limitations under the License. | ||
|
||
#include <string> | ||
|
||
#include "absl/status/status.h" // from @com_google_absl | ||
#include "absl/strings/cord.h" // from @com_google_absl | ||
|
||
#include "tensorflow_lite_support/cc/common.h" | ||
|
||
#import "tensorflow_lite_support/ios/sources/TFLCommon.h" | ||
#import "tensorflow_lite_support/ios/sources/TFLCommonCppUtils.h" | ||
|
||
@implementation TFLCommonCppUtils | ||
|
||
+ (BOOL)checkCError:(TfLiteSupportError *)supportError toError:(NSError **)error { | ||
if (!supportError) { | ||
return YES; | ||
} | ||
NSString *description = [NSString stringWithCString:supportError->message | ||
encoding:NSUTF8StringEncoding]; | ||
[TFLCommonUtils createCustomError:error withCode:supportError->code description:description]; | ||
return NO; | ||
} | ||
|
||
+ (BOOL)checkCppError:(const absl::Status &)status toError:(NSError *_Nullable *)error { | ||
if (!status.ok()) { | ||
return YES; | ||
} | ||
// Payload of absl::Status created by the tflite task library stores an appropriate value of the | ||
// enum TfLiteSupportStatus. The integer value corresponding to the TfLiteSupportStatus enum | ||
// stored in the payload is extracted here to later map to the appropriate error code to be | ||
// returned. In cases where the enum is not stored in (payload is NULL or the payload string | ||
// cannot be converted to an integer), we set the error code value to be 1 | ||
// (TFLSupportErrorCodeUnspecifiedError of TFLSupportErrorCode used in the iOS library to signify | ||
// any errors not falling into other categories.) Since payload is of type absl::Cord that can be | ||
// type cast into an absl::optional<std::string>, we use the std::stoi function to convert it into | ||
// an integer code if possible. | ||
NSUInteger genericErrorCode = TFLSupportErrorCodeUnspecifiedError; | ||
NSUInteger errorCode; | ||
try { | ||
// Try converting payload to integer if payload is not empty. Otherwise convert a string | ||
// signifying generic error code TFLSupportErrorCodeUnspecifiedError to integer. | ||
errorCode = | ||
(NSUInteger)std::stoi(static_cast<absl::optional<std::string>>( | ||
status.GetPayload(tflite::support::kTfLiteSupportPayload)) | ||
.value_or(std::to_string(genericErrorCode))); | ||
} catch (std::invalid_argument &e) { | ||
// If non empty payload string cannot be converted to an integer. Set error code to 1(kError). | ||
errorCode = TFLSupportErrorCodeUnspecifiedError; | ||
} | ||
|
||
// If errorCode is outside the range of enum values possible or is | ||
// TFLSupportErrorCodeUnspecifiedError, we try to map the absl::Status::code() to assign | ||
// appropriate TFLSupportErrorCode or TFLSupportErrorCodeUnspecifiedError in default cases. Note: | ||
// The mapping to absl::Status::code() is done to generate a more specific error code than | ||
// TFLSupportErrorCodeUnspecifiedError in cases when the payload can't be mapped to | ||
// TfLiteSupportStatus. This can happen when absl::Status returned by TfLite are in turn returned | ||
// without moodification by TfLite Support Methods. | ||
if (errorCode > TFLErrorCodeLast || errorCode <= TFLErrorCodeFirst) { | ||
switch (status.code()) { | ||
case absl::StatusCode::kInternal: | ||
errorCode = TFLSupportErrorCodeInternalError; | ||
break; | ||
case absl::StatusCode::kInvalidArgument: | ||
errorCode = TFLSupportErrorCodeInvalidArgumentError; | ||
break; | ||
case absl::StatusCode::kNotFound: | ||
errorCode = TFLSupportErrorCodeNotFoundError; | ||
break; | ||
default: | ||
errorCode = TFLSupportErrorCodeUnspecifiedError; | ||
break; | ||
} | ||
} | ||
|
||
// Creates the NSEror with the appropriate error | ||
// TFLSupportErrorCode and message. TFLSupportErrorCode has a one to one | ||
// mapping with TfLiteSupportStatus starting from the value 1(TFLSupportErrorCodeUnspecifiedError) | ||
// and hence will be correctly initialized if directly cast from the integer code derived from | ||
// TfLiteSupportStatus stored in its payload. TFLSupportErrorCode omits kOk = 0 of | ||
// TfLiteSupportStatus. | ||
// | ||
// Stores a string including absl status code and message(if non empty) as the | ||
// error message See | ||
// https://github.com/abseil/abseil-cpp/blob/master/absl/status/status.h#L514 | ||
// for explanation. absl::Status::message() can also be used but not always | ||
// guaranteed to be non empty. | ||
NSString *description = [NSString | ||
stringWithCString:status.ToString(absl::StatusToStringMode::kWithNoExtraData).c_str() | ||
encoding:NSUTF8StringEncoding]; | ||
[TFLCommonUtils createCustomError:error withCode:errorCode description:description]; | ||
return NO; | ||
} | ||
|
||
@end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters