libbinder: Add support for Value, Map, and IpPrefix types
Change-Id: I4cd06c7c65f69e6b787111573b29c4ff22f57981
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index a6ccb53..da94305 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -37,6 +37,7 @@
#include <binder/ProcessState.h>
#include <binder/Status.h>
#include <binder/TextOutput.h>
+#include <binder/Value.h>
#include <cutils/ashmem.h>
#include <utils/Debug.h>
@@ -1106,6 +1107,10 @@
return parcelable.writeToParcel(this);
}
+status_t Parcel::writeValue(const binder::Value& value) {
+ return value.writeToParcel(this);
+}
+
status_t Parcel::writeNativeHandle(const native_handle* handle)
{
if (!handle || handle->version != sizeof(native_handle))
@@ -1330,6 +1335,120 @@
return status.writeToParcel(this);
}
+status_t Parcel::writeMap(const ::android::binder::Map& map_in)
+{
+ using ::std::map;
+ using ::android::binder::Value;
+ using ::android::binder::Map;
+
+ Map::const_iterator iter;
+ status_t ret;
+
+ ret = writeInt32(map_in.size());
+
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
+ for (iter = map_in.begin(); iter != map_in.end(); ++iter) {
+ ret = writeValue(Value(iter->first));
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
+ ret = writeValue(iter->second);
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+ }
+
+ return ret;
+}
+
+status_t Parcel::writeNullableMap(const std::unique_ptr<binder::Map>& map)
+{
+ if (map == NULL) {
+ return writeInt32(-1);
+ }
+
+ return writeMap(*map.get());
+}
+
+status_t Parcel::readMap(::android::binder::Map* map_out)const
+{
+ using ::std::map;
+ using ::android::String16;
+ using ::android::String8;
+ using ::android::binder::Value;
+ using ::android::binder::Map;
+
+ status_t ret = NO_ERROR;
+ int32_t count;
+
+ ret = readInt32(&count);
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
+ if (count < 0) {
+ ALOGE("readMap: Unexpected count: %d", count);
+ return (count == -1)
+ ? UNEXPECTED_NULL
+ : BAD_VALUE;
+ }
+
+ map_out->clear();
+
+ while (count--) {
+ Map::key_type key;
+ Value value;
+
+ ret = readValue(&value);
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
+ if (!value.getString(&key)) {
+ ALOGE("readMap: Key type not a string (parcelType = %d)", value.parcelType());
+ return BAD_VALUE;
+ }
+
+ ret = readValue(&value);
+ if (ret != NO_ERROR) {
+ return ret;
+ }
+
+ (*map_out)[key] = value;
+ }
+
+ return ret;
+}
+
+status_t Parcel::readNullableMap(std::unique_ptr<binder::Map>* map) const
+{
+ const size_t start = dataPosition();
+ int32_t count;
+ status_t status = readInt32(&count);
+ map->reset();
+
+ if (status != OK || count == -1) {
+ return status;
+ }
+
+ setDataPosition(start);
+ map->reset(new binder::Map());
+
+ status = readMap(map->get());
+
+ if (status != OK) {
+ map->reset();
+ }
+
+ return status;
+}
+
+
+
void Parcel::remove(size_t /*start*/, size_t /*amt*/)
{
LOG_ALWAYS_FATAL("Parcel::remove() not yet implemented!");
@@ -1950,6 +2069,10 @@
return parcelable->readFromParcel(this);
}
+status_t Parcel::readValue(binder::Value* value) const {
+ return value->readFromParcel(this);
+}
+
int32_t Parcel::readExceptionCode() const
{
binder::Status status;