forked from google/ink
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add storage (serialization/deserialization) module
PiperOrigin-RevId: 716350769
- Loading branch information
1 parent
65e368b
commit a5e555b
Showing
45 changed files
with
8,090 additions
and
7 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
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,80 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// 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 "ink/jni/internal/jni_proto_util.h" | ||
|
||
#include <jni.h> | ||
|
||
#include <cstddef> | ||
|
||
#include "absl/log/absl_check.h" | ||
#include "absl/status/status.h" | ||
#include "absl/strings/str_cat.h" | ||
#include "google/protobuf/message_lite.h" | ||
|
||
namespace ink { | ||
namespace jni { | ||
|
||
absl::Status ParseProto(JNIEnv* env, jbyteArray serialized_proto, | ||
google::protobuf::MessageLite& dest) { | ||
return ParseProto(env, serialized_proto, 0, | ||
env->GetArrayLength(serialized_proto), dest); | ||
} | ||
|
||
absl::Status ParseProto(JNIEnv* env, jbyteArray serialized_proto, jint offset, | ||
jint size, google::protobuf::MessageLite& dest) { | ||
// TODO(b/290213178): See how often this copies using the isCopy pointer | ||
// argument, and consider using critical arrays to minimize copying. | ||
jbyte* bytes = env->GetByteArrayElements(serialized_proto, nullptr); | ||
ABSL_CHECK(bytes); | ||
bool success = dest.ParseFromArray(bytes + offset, size); | ||
env->ReleaseByteArrayElements(serialized_proto, bytes, 0); | ||
if (!success) { | ||
return absl::InvalidArgumentError(absl::StrCat( | ||
"Failed to parse ", dest.GetTypeName(), " proto from byte[].")); | ||
} | ||
return absl::OkStatus(); | ||
} | ||
|
||
absl::Status ParseProtoFromBuffer(JNIEnv* env, | ||
jobject serialized_proto_direct_buffer, | ||
jint offset, jint size, | ||
google::protobuf::MessageLite& dest) { | ||
void* addr = env->GetDirectBufferAddress(serialized_proto_direct_buffer); | ||
ABSL_CHECK(addr); | ||
// Cannot do arithmetic on void* due to unknown size of elements, so | ||
// explicitly cast to clarify that the offset (and size) are in bytes. | ||
jbyte* bytes = static_cast<jbyte*>(addr); | ||
bool success = dest.ParseFromArray(bytes + offset, size); | ||
if (!success) { | ||
return absl::InvalidArgumentError(absl::StrCat( | ||
"Failed to parse ", dest.GetTypeName(), " proto from direct buffer.")); | ||
} | ||
return absl::OkStatus(); | ||
} | ||
|
||
jbyteArray SerializeProto(JNIEnv* env, const google::protobuf::MessageLite& src) { | ||
size_t size = src.ByteSizeLong(); | ||
jbyteArray serialized_proto = env->NewByteArray(size); | ||
ABSL_CHECK(serialized_proto); | ||
jbyte* bytes = env->GetByteArrayElements(serialized_proto, nullptr); | ||
ABSL_CHECK(bytes); | ||
bool success = src.SerializeToArray(bytes, size); | ||
env->ReleaseByteArrayElements(serialized_proto, bytes, 0); | ||
ABSL_CHECK(success); | ||
return serialized_proto; | ||
} | ||
|
||
} // namespace jni | ||
} // namespace ink |
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,56 @@ | ||
// Copyright 2024 Google LLC | ||
// | ||
// 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. | ||
|
||
#ifndef INK_JNI_INTERNAL_JNI_PROTO_UTIL_H_ | ||
#define INK_JNI_INTERNAL_JNI_PROTO_UTIL_H_ | ||
|
||
#include <jni.h> | ||
|
||
#include "absl/status/status.h" | ||
#include "google/protobuf/message_lite.h" | ||
|
||
namespace ink { | ||
namespace jni { | ||
|
||
// Attempts to parse a serialized proto. If the proto doesn't parse, returns | ||
// a non-OK absl::Status. | ||
[[nodiscard]] absl::Status ParseProto(JNIEnv* env, jbyteArray serialized_proto, | ||
google::protobuf::MessageLite& dest); | ||
|
||
// Attempts to parse a serialized proto. If the proto doesn't parse, returns | ||
// a non-OK absl::Status. `offset` is the starting point of the data within the | ||
// `serialized_proto` array, and `size` is how far beyond `offset` the data | ||
// continues. | ||
[[nodiscard]] absl::Status ParseProto(JNIEnv* env, jbyteArray serialized_proto, | ||
jint offset, jint size, | ||
google::protobuf::MessageLite& dest); | ||
|
||
// Attempts to parse a serialized proto from a direct java.nio.ByteBuffer. If | ||
// the proto doesn't parse, returns a non-OK absl::Status. `offset` is the | ||
// starting point of the data within the `serialized_proto` array, and `size` | ||
// is how far beyond `offset` the data continues. | ||
// Note: This has a different name than `ParseProto`, as jbyteArray is a type of | ||
// jobject so the two definitions would clash rather than serve as overloads. | ||
[[nodiscard]] absl::Status ParseProtoFromBuffer( | ||
JNIEnv* env, jobject serialized_proto_direct_buffer, jint offset, jint size, | ||
google::protobuf::MessageLite& dest); | ||
|
||
// Serializes a proto into a newly-allocated Java byte array. | ||
[[nodiscard]] jbyteArray SerializeProto(JNIEnv* env, | ||
const google::protobuf::MessageLite& src); | ||
|
||
} // namespace jni | ||
} // namespace ink | ||
|
||
#endif // INK_JNI_INTERNAL_JNI_PROTO_UTIL_H_ |
Oops, something went wrong.