Loading libs/protoutil/include/android/util/ProtoOutputStream.h +12 −8 Original line number Original line Diff line number Diff line Loading @@ -17,10 +17,11 @@ #ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H #ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H #define ANDROID_UTIL_PROTOOUTPUT_STREAM_H #define ANDROID_UTIL_PROTOOUTPUT_STREAM_H #include <android/util/EncodedBuffer.h> #include <cstdint> #include <string> #include <string> #include <android/util/EncodedBuffer.h> namespace android { namespace android { namespace util { namespace util { Loading Loading @@ -143,16 +144,16 @@ private: inline void writeDoubleImpl(uint32_t id, double val); inline void writeDoubleImpl(uint32_t id, double val); inline void writeFloatImpl(uint32_t id, float val); inline void writeFloatImpl(uint32_t id, float val); inline void writeInt64Impl(uint32_t id, long long val); inline void writeInt64Impl(uint32_t id, int64_t val); inline void writeInt32Impl(uint32_t id, int val); inline void writeInt32Impl(uint32_t id, int32_t val); inline void writeUint64Impl(uint32_t id, uint64_t val); inline void writeUint64Impl(uint32_t id, uint64_t val); inline void writeUint32Impl(uint32_t id, uint32_t val); inline void writeUint32Impl(uint32_t id, uint32_t val); inline void writeFixed64Impl(uint32_t id, uint64_t val); inline void writeFixed64Impl(uint32_t id, uint64_t val); inline void writeFixed32Impl(uint32_t id, uint32_t val); inline void writeFixed32Impl(uint32_t id, uint32_t val); inline void writeSFixed64Impl(uint32_t id, long long val); inline void writeSFixed64Impl(uint32_t id, int64_t val); inline void writeSFixed32Impl(uint32_t id, int val); inline void writeSFixed32Impl(uint32_t id, int32_t val); inline void writeZigzagInt64Impl(uint32_t id, long long val); inline void writeZigzagInt64Impl(uint32_t id, int64_t val); inline void writeZigzagInt32Impl(uint32_t id, int val); inline void writeZigzagInt32Impl(uint32_t id, int32_t val); inline void writeEnumImpl(uint32_t id, int val); inline void writeEnumImpl(uint32_t id, int val); inline void writeBoolImpl(uint32_t id, bool val); inline void writeBoolImpl(uint32_t id, bool val); inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size); inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size); Loading @@ -161,6 +162,9 @@ private: bool compact(); bool compact(); size_t editEncodedSize(size_t rawSize); size_t editEncodedSize(size_t rawSize); bool compactSize(size_t rawSize); bool compactSize(size_t rawSize); template<typename T> bool internalWrite(uint64_t fieldId, T val, const char* typeName); }; }; } } Loading libs/protoutil/src/ProtoOutputStream.cpp +56 −94 Original line number Original line Diff line number Diff line Loading @@ -15,7 +15,8 @@ */ */ #define LOG_TAG "libprotoutil" #define LOG_TAG "libprotoutil" #include <inttypes.h> #include <cinttypes> #include <type_traits> #include <android-base/file.h> #include <android-base/file.h> #include <android/util/protobuf.h> #include <android/util/protobuf.h> Loading Loading @@ -51,112 +52,73 @@ ProtoOutputStream::clear() mExpectedObjectToken = UINT64_C(-1); mExpectedObjectToken = UINT64_C(-1); } } template<typename T> bool bool ProtoOutputStream::write(uint64_t fieldId, double val) ProtoOutputStream::internalWrite(uint64_t fieldId, T val, const char* typeName) { { if (mCompact) return false; if (mCompact) return false; const uint32_t id = (uint32_t)fieldId; const uint32_t id = (uint32_t)fieldId; switch (fieldId & FIELD_TYPE_MASK) { switch (fieldId & FIELD_TYPE_MASK) { case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (int64_t)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int32_t)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int32_t)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (int64_t)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int32_t)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (int64_t)val); break; case FIELD_TYPE_ENUM: if (std::is_integral<T>::value) { writeEnumImpl(id, (int)val); } else { goto unsupported; } break; case FIELD_TYPE_BOOL: if (std::is_integral<T>::value) { writeBoolImpl(id, val != 0); } else { goto unsupported; } break; default: default: ALOGW("Field type %d is not supported when writing double val.", goto unsupported; (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; } } return true; return true; unsupported: ALOGW("Field type %" PRIu64 " is not supported when writing %s val.", (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT, typeName); return false; } } bool bool ProtoOutputStream::write(uint64_t fieldId, float val) ProtoOutputStream::write(uint64_t fieldId, double val) { { if (mCompact) return false; return internalWrite(fieldId, val, "double"); const uint32_t id = (uint32_t)fieldId; switch (fieldId & FIELD_TYPE_MASK) { case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break; default: ALOGW("Field type %d is not supported when writing float val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; } } return true; bool ProtoOutputStream::write(uint64_t fieldId, float val) { return internalWrite(fieldId, val, "float"); } } bool bool ProtoOutputStream::write(uint64_t fieldId, int val) ProtoOutputStream::write(uint64_t fieldId, int val) { { if (mCompact) return false; return internalWrite(fieldId, val, "int"); const uint32_t id = (uint32_t)fieldId; switch (fieldId & FIELD_TYPE_MASK) { case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break; case FIELD_TYPE_ENUM: writeEnumImpl(id, (int)val); break; case FIELD_TYPE_BOOL: writeBoolImpl(id, val != 0); break; default: ALOGW("Field type %d is not supported when writing int val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; } return true; } } bool bool ProtoOutputStream::write(uint64_t fieldId, long long val) ProtoOutputStream::write(uint64_t fieldId, long long val) { { if (mCompact) return false; return internalWrite(fieldId, val, "long long"); const uint32_t id = (uint32_t)fieldId; switch (fieldId & FIELD_TYPE_MASK) { case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break; case FIELD_TYPE_ENUM: writeEnumImpl(id, (int)val); break; case FIELD_TYPE_BOOL: writeBoolImpl(id, val != 0); break; default: ALOGW("Field type %d is not supported when writing long long val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; } return true; } } bool bool Loading @@ -169,8 +131,8 @@ ProtoOutputStream::write(uint64_t fieldId, bool val) writeBoolImpl(id, val); writeBoolImpl(id, val); return true; return true; default: default: ALOGW("Field type %d is not supported when writing bool val.", ALOGW("Field type %" PRIu64 " is not supported when writing bool val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; return false; } } } } Loading @@ -185,8 +147,8 @@ ProtoOutputStream::write(uint64_t fieldId, std::string val) writeUtf8StringImpl(id, val.c_str(), val.size()); writeUtf8StringImpl(id, val.c_str(), val.size()); return true; return true; default: default: ALOGW("Field type %d is not supported when writing string val.", ALOGW("Field type %" PRIu64 " is not supported when writing string val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; return false; } } } } Loading @@ -206,8 +168,8 @@ ProtoOutputStream::write(uint64_t fieldId, const char* val, size_t size) writeMessageBytesImpl(id, val, size); writeMessageBytesImpl(id, val, size); return true; return true; default: default: ALOGW("Field type %d is not supported when writing char[] val.", ALOGW("Field type %" PRIu64 " is not supported when writing char[] val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; return false; } } } } Loading Loading @@ -542,17 +504,17 @@ ProtoOutputStream::writeFloatImpl(uint32_t id, float val) } } inline void inline void ProtoOutputStream::writeInt64Impl(uint32_t id, long long val) ProtoOutputStream::writeInt64Impl(uint32_t id, int64_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint64((uint64_t)val); mBuffer.writeRawVarint64(val); } } inline void inline void ProtoOutputStream::writeInt32Impl(uint32_t id, int val) ProtoOutputStream::writeInt32Impl(uint32_t id, int32_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint32((uint32_t)val); mBuffer.writeRawVarint32(val); } } inline void inline void Loading Loading @@ -584,28 +546,28 @@ ProtoOutputStream::writeFixed32Impl(uint32_t id, uint32_t val) } } inline void inline void ProtoOutputStream::writeSFixed64Impl(uint32_t id, long long val) ProtoOutputStream::writeSFixed64Impl(uint32_t id, int64_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_FIXED64); mBuffer.writeHeader(id, WIRE_TYPE_FIXED64); mBuffer.writeRawFixed64((uint64_t)val); mBuffer.writeRawFixed64(val); } } inline void inline void ProtoOutputStream::writeSFixed32Impl(uint32_t id, int val) ProtoOutputStream::writeSFixed32Impl(uint32_t id, int32_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_FIXED32); mBuffer.writeHeader(id, WIRE_TYPE_FIXED32); mBuffer.writeRawFixed32((uint32_t)val); mBuffer.writeRawFixed32(val); } } inline void inline void ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, long long val) ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, int64_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint64((val << 1) ^ (val >> 63)); mBuffer.writeRawVarint64((val << 1) ^ (val >> 63)); } } inline void inline void ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int val) ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int32_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint32((val << 1) ^ (val >> 31)); mBuffer.writeRawVarint32((val << 1) ^ (val >> 31)); Loading libs/protoutil/tests/ProtoOutputStream_test.cpp +25 −3 Original line number Original line Diff line number Diff line Loading @@ -132,17 +132,31 @@ TEST(ProtoOutputStreamTest, Reusability) { EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 15)); EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 15)); EXPECT_EQ(proto.bytesWritten(), 4); EXPECT_EQ(proto.bytesWritten(), 4); EXPECT_EQ(proto.size(), 4); EXPECT_EQ(proto.size(), 4); // Can't write to proto after compact EXPECT_FALSE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 94)); ComplexProto beforeClear; ASSERT_TRUE(beforeClear.ParseFromString(flushToString(&proto))); EXPECT_EQ(beforeClear.ints_size(), 2); EXPECT_EQ(beforeClear.ints(0), 32); EXPECT_EQ(beforeClear.ints(1), 15); proto.clear(); proto.clear(); EXPECT_EQ(proto.bytesWritten(), 0); EXPECT_EQ(proto.bytesWritten(), 0); EXPECT_EQ(proto.size(), 0); EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 1076)); ComplexProto afterClear; ASSERT_TRUE(afterClear.ParseFromString(flushToString(&proto))); EXPECT_EQ(afterClear.ints_size(), 1); EXPECT_EQ(afterClear.ints(0), 1076); } } TEST(ProtoOutputStreamTest, AdvancedEncoding) { TEST(ProtoOutputStreamTest, AdvancedEncoding) { ProtoOutputStream proto; ProtoOutputStream proto; proto.writeRawVarint(ComplexProto::kIntsFieldNumber << FIELD_ID_SHIFT); proto.writeRawVarint((ComplexProto::kIntsFieldNumber << FIELD_ID_SHIFT) + WIRE_TYPE_VARINT); proto.writeRawVarint(UINT64_C(-123809234)); proto.writeRawVarint(UINT64_C(-123809234)); proto.writeLengthDelimitedHeader(ComplexProto::kLogsFieldNumber, 8); proto.writeLengthDelimitedHeader(ComplexProto::kLogsFieldNumber, 8); proto.writeRawByte((ComplexProto::Log::kDataFieldNumber << FIELD_ID_SHIFT) + 2); proto.writeRawByte((ComplexProto::Log::kDataFieldNumber << FIELD_ID_SHIFT) + WIRE_TYPE_LENGTH_DELIMITED); proto.writeRawByte(6); proto.writeRawByte(6); proto.writeRawByte('b'); proto.writeRawByte('b'); proto.writeRawByte('a'); proto.writeRawByte('a'); Loading @@ -168,3 +182,11 @@ TEST(ProtoOutputStreamTest, AdvancedEncoding) { EXPECT_FALSE(log2.has_name()); EXPECT_FALSE(log2.has_name()); EXPECT_FALSE(log2.has_data()); EXPECT_FALSE(log2.has_data()); } } TEST(ProtoOutputStreamTest, InvalidTypes) { ProtoOutputStream proto; EXPECT_FALSE(proto.write(FIELD_TYPE_UNKNOWN | PrimitiveProto::kValInt32FieldNumber, 790)); EXPECT_FALSE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 234.34)); EXPECT_FALSE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, 18.73f)); EXPECT_EQ(proto.size(), 0); } No newline at end of file Loading
libs/protoutil/include/android/util/ProtoOutputStream.h +12 −8 Original line number Original line Diff line number Diff line Loading @@ -17,10 +17,11 @@ #ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H #ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H #define ANDROID_UTIL_PROTOOUTPUT_STREAM_H #define ANDROID_UTIL_PROTOOUTPUT_STREAM_H #include <android/util/EncodedBuffer.h> #include <cstdint> #include <string> #include <string> #include <android/util/EncodedBuffer.h> namespace android { namespace android { namespace util { namespace util { Loading Loading @@ -143,16 +144,16 @@ private: inline void writeDoubleImpl(uint32_t id, double val); inline void writeDoubleImpl(uint32_t id, double val); inline void writeFloatImpl(uint32_t id, float val); inline void writeFloatImpl(uint32_t id, float val); inline void writeInt64Impl(uint32_t id, long long val); inline void writeInt64Impl(uint32_t id, int64_t val); inline void writeInt32Impl(uint32_t id, int val); inline void writeInt32Impl(uint32_t id, int32_t val); inline void writeUint64Impl(uint32_t id, uint64_t val); inline void writeUint64Impl(uint32_t id, uint64_t val); inline void writeUint32Impl(uint32_t id, uint32_t val); inline void writeUint32Impl(uint32_t id, uint32_t val); inline void writeFixed64Impl(uint32_t id, uint64_t val); inline void writeFixed64Impl(uint32_t id, uint64_t val); inline void writeFixed32Impl(uint32_t id, uint32_t val); inline void writeFixed32Impl(uint32_t id, uint32_t val); inline void writeSFixed64Impl(uint32_t id, long long val); inline void writeSFixed64Impl(uint32_t id, int64_t val); inline void writeSFixed32Impl(uint32_t id, int val); inline void writeSFixed32Impl(uint32_t id, int32_t val); inline void writeZigzagInt64Impl(uint32_t id, long long val); inline void writeZigzagInt64Impl(uint32_t id, int64_t val); inline void writeZigzagInt32Impl(uint32_t id, int val); inline void writeZigzagInt32Impl(uint32_t id, int32_t val); inline void writeEnumImpl(uint32_t id, int val); inline void writeEnumImpl(uint32_t id, int val); inline void writeBoolImpl(uint32_t id, bool val); inline void writeBoolImpl(uint32_t id, bool val); inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size); inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size); Loading @@ -161,6 +162,9 @@ private: bool compact(); bool compact(); size_t editEncodedSize(size_t rawSize); size_t editEncodedSize(size_t rawSize); bool compactSize(size_t rawSize); bool compactSize(size_t rawSize); template<typename T> bool internalWrite(uint64_t fieldId, T val, const char* typeName); }; }; } } Loading
libs/protoutil/src/ProtoOutputStream.cpp +56 −94 Original line number Original line Diff line number Diff line Loading @@ -15,7 +15,8 @@ */ */ #define LOG_TAG "libprotoutil" #define LOG_TAG "libprotoutil" #include <inttypes.h> #include <cinttypes> #include <type_traits> #include <android-base/file.h> #include <android-base/file.h> #include <android/util/protobuf.h> #include <android/util/protobuf.h> Loading Loading @@ -51,112 +52,73 @@ ProtoOutputStream::clear() mExpectedObjectToken = UINT64_C(-1); mExpectedObjectToken = UINT64_C(-1); } } template<typename T> bool bool ProtoOutputStream::write(uint64_t fieldId, double val) ProtoOutputStream::internalWrite(uint64_t fieldId, T val, const char* typeName) { { if (mCompact) return false; if (mCompact) return false; const uint32_t id = (uint32_t)fieldId; const uint32_t id = (uint32_t)fieldId; switch (fieldId & FIELD_TYPE_MASK) { switch (fieldId & FIELD_TYPE_MASK) { case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (int64_t)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int32_t)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int32_t)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (int64_t)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int32_t)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (int64_t)val); break; case FIELD_TYPE_ENUM: if (std::is_integral<T>::value) { writeEnumImpl(id, (int)val); } else { goto unsupported; } break; case FIELD_TYPE_BOOL: if (std::is_integral<T>::value) { writeBoolImpl(id, val != 0); } else { goto unsupported; } break; default: default: ALOGW("Field type %d is not supported when writing double val.", goto unsupported; (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; } } return true; return true; unsupported: ALOGW("Field type %" PRIu64 " is not supported when writing %s val.", (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT, typeName); return false; } } bool bool ProtoOutputStream::write(uint64_t fieldId, float val) ProtoOutputStream::write(uint64_t fieldId, double val) { { if (mCompact) return false; return internalWrite(fieldId, val, "double"); const uint32_t id = (uint32_t)fieldId; switch (fieldId & FIELD_TYPE_MASK) { case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break; default: ALOGW("Field type %d is not supported when writing float val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; } } return true; bool ProtoOutputStream::write(uint64_t fieldId, float val) { return internalWrite(fieldId, val, "float"); } } bool bool ProtoOutputStream::write(uint64_t fieldId, int val) ProtoOutputStream::write(uint64_t fieldId, int val) { { if (mCompact) return false; return internalWrite(fieldId, val, "int"); const uint32_t id = (uint32_t)fieldId; switch (fieldId & FIELD_TYPE_MASK) { case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break; case FIELD_TYPE_ENUM: writeEnumImpl(id, (int)val); break; case FIELD_TYPE_BOOL: writeBoolImpl(id, val != 0); break; default: ALOGW("Field type %d is not supported when writing int val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; } return true; } } bool bool ProtoOutputStream::write(uint64_t fieldId, long long val) ProtoOutputStream::write(uint64_t fieldId, long long val) { { if (mCompact) return false; return internalWrite(fieldId, val, "long long"); const uint32_t id = (uint32_t)fieldId; switch (fieldId & FIELD_TYPE_MASK) { case FIELD_TYPE_DOUBLE: writeDoubleImpl(id, (double)val); break; case FIELD_TYPE_FLOAT: writeFloatImpl(id, (float)val); break; case FIELD_TYPE_INT64: writeInt64Impl(id, (long long)val); break; case FIELD_TYPE_UINT64: writeUint64Impl(id, (uint64_t)val); break; case FIELD_TYPE_INT32: writeInt32Impl(id, (int)val); break; case FIELD_TYPE_FIXED64: writeFixed64Impl(id, (uint64_t)val); break; case FIELD_TYPE_FIXED32: writeFixed32Impl(id, (uint32_t)val); break; case FIELD_TYPE_UINT32: writeUint32Impl(id, (uint32_t)val); break; case FIELD_TYPE_SFIXED32: writeSFixed32Impl(id, (int)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (long long)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int)val); break; case FIELD_TYPE_SINT64: writeZigzagInt64Impl(id, (long long)val); break; case FIELD_TYPE_ENUM: writeEnumImpl(id, (int)val); break; case FIELD_TYPE_BOOL: writeBoolImpl(id, val != 0); break; default: ALOGW("Field type %d is not supported when writing long long val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; } return true; } } bool bool Loading @@ -169,8 +131,8 @@ ProtoOutputStream::write(uint64_t fieldId, bool val) writeBoolImpl(id, val); writeBoolImpl(id, val); return true; return true; default: default: ALOGW("Field type %d is not supported when writing bool val.", ALOGW("Field type %" PRIu64 " is not supported when writing bool val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; return false; } } } } Loading @@ -185,8 +147,8 @@ ProtoOutputStream::write(uint64_t fieldId, std::string val) writeUtf8StringImpl(id, val.c_str(), val.size()); writeUtf8StringImpl(id, val.c_str(), val.size()); return true; return true; default: default: ALOGW("Field type %d is not supported when writing string val.", ALOGW("Field type %" PRIu64 " is not supported when writing string val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; return false; } } } } Loading @@ -206,8 +168,8 @@ ProtoOutputStream::write(uint64_t fieldId, const char* val, size_t size) writeMessageBytesImpl(id, val, size); writeMessageBytesImpl(id, val, size); return true; return true; default: default: ALOGW("Field type %d is not supported when writing char[] val.", ALOGW("Field type %" PRIu64 " is not supported when writing char[] val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; return false; } } } } Loading Loading @@ -542,17 +504,17 @@ ProtoOutputStream::writeFloatImpl(uint32_t id, float val) } } inline void inline void ProtoOutputStream::writeInt64Impl(uint32_t id, long long val) ProtoOutputStream::writeInt64Impl(uint32_t id, int64_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint64((uint64_t)val); mBuffer.writeRawVarint64(val); } } inline void inline void ProtoOutputStream::writeInt32Impl(uint32_t id, int val) ProtoOutputStream::writeInt32Impl(uint32_t id, int32_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint32((uint32_t)val); mBuffer.writeRawVarint32(val); } } inline void inline void Loading Loading @@ -584,28 +546,28 @@ ProtoOutputStream::writeFixed32Impl(uint32_t id, uint32_t val) } } inline void inline void ProtoOutputStream::writeSFixed64Impl(uint32_t id, long long val) ProtoOutputStream::writeSFixed64Impl(uint32_t id, int64_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_FIXED64); mBuffer.writeHeader(id, WIRE_TYPE_FIXED64); mBuffer.writeRawFixed64((uint64_t)val); mBuffer.writeRawFixed64(val); } } inline void inline void ProtoOutputStream::writeSFixed32Impl(uint32_t id, int val) ProtoOutputStream::writeSFixed32Impl(uint32_t id, int32_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_FIXED32); mBuffer.writeHeader(id, WIRE_TYPE_FIXED32); mBuffer.writeRawFixed32((uint32_t)val); mBuffer.writeRawFixed32(val); } } inline void inline void ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, long long val) ProtoOutputStream::writeZigzagInt64Impl(uint32_t id, int64_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint64((val << 1) ^ (val >> 63)); mBuffer.writeRawVarint64((val << 1) ^ (val >> 63)); } } inline void inline void ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int val) ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int32_t val) { { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint32((val << 1) ^ (val >> 31)); mBuffer.writeRawVarint32((val << 1) ^ (val >> 31)); Loading
libs/protoutil/tests/ProtoOutputStream_test.cpp +25 −3 Original line number Original line Diff line number Diff line Loading @@ -132,17 +132,31 @@ TEST(ProtoOutputStreamTest, Reusability) { EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 15)); EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 15)); EXPECT_EQ(proto.bytesWritten(), 4); EXPECT_EQ(proto.bytesWritten(), 4); EXPECT_EQ(proto.size(), 4); EXPECT_EQ(proto.size(), 4); // Can't write to proto after compact EXPECT_FALSE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 94)); ComplexProto beforeClear; ASSERT_TRUE(beforeClear.ParseFromString(flushToString(&proto))); EXPECT_EQ(beforeClear.ints_size(), 2); EXPECT_EQ(beforeClear.ints(0), 32); EXPECT_EQ(beforeClear.ints(1), 15); proto.clear(); proto.clear(); EXPECT_EQ(proto.bytesWritten(), 0); EXPECT_EQ(proto.bytesWritten(), 0); EXPECT_EQ(proto.size(), 0); EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 1076)); ComplexProto afterClear; ASSERT_TRUE(afterClear.ParseFromString(flushToString(&proto))); EXPECT_EQ(afterClear.ints_size(), 1); EXPECT_EQ(afterClear.ints(0), 1076); } } TEST(ProtoOutputStreamTest, AdvancedEncoding) { TEST(ProtoOutputStreamTest, AdvancedEncoding) { ProtoOutputStream proto; ProtoOutputStream proto; proto.writeRawVarint(ComplexProto::kIntsFieldNumber << FIELD_ID_SHIFT); proto.writeRawVarint((ComplexProto::kIntsFieldNumber << FIELD_ID_SHIFT) + WIRE_TYPE_VARINT); proto.writeRawVarint(UINT64_C(-123809234)); proto.writeRawVarint(UINT64_C(-123809234)); proto.writeLengthDelimitedHeader(ComplexProto::kLogsFieldNumber, 8); proto.writeLengthDelimitedHeader(ComplexProto::kLogsFieldNumber, 8); proto.writeRawByte((ComplexProto::Log::kDataFieldNumber << FIELD_ID_SHIFT) + 2); proto.writeRawByte((ComplexProto::Log::kDataFieldNumber << FIELD_ID_SHIFT) + WIRE_TYPE_LENGTH_DELIMITED); proto.writeRawByte(6); proto.writeRawByte(6); proto.writeRawByte('b'); proto.writeRawByte('b'); proto.writeRawByte('a'); proto.writeRawByte('a'); Loading @@ -168,3 +182,11 @@ TEST(ProtoOutputStreamTest, AdvancedEncoding) { EXPECT_FALSE(log2.has_name()); EXPECT_FALSE(log2.has_name()); EXPECT_FALSE(log2.has_data()); EXPECT_FALSE(log2.has_data()); } } TEST(ProtoOutputStreamTest, InvalidTypes) { ProtoOutputStream proto; EXPECT_FALSE(proto.write(FIELD_TYPE_UNKNOWN | PrimitiveProto::kValInt32FieldNumber, 790)); EXPECT_FALSE(proto.write(FIELD_TYPE_ENUM | PrimitiveProto::kValEnumFieldNumber, 234.34)); EXPECT_FALSE(proto.write(FIELD_TYPE_BOOL | PrimitiveProto::kValBoolFieldNumber, 18.73f)); EXPECT_EQ(proto.size(), 0); } No newline at end of file