Loading libs/protoutil/include/android/util/ProtoOutputStream.h +12 −8 Original line number Diff line number Diff line Loading @@ -17,10 +17,11 @@ #ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H #define ANDROID_UTIL_PROTOOUTPUT_STREAM_H #include <android/util/EncodedBuffer.h> #include <cstdint> #include <string> #include <android/util/EncodedBuffer.h> namespace android { namespace util { Loading Loading @@ -143,16 +144,16 @@ private: inline void writeDoubleImpl(uint32_t id, double val); inline void writeFloatImpl(uint32_t id, float val); inline void writeInt64Impl(uint32_t id, long long val); inline void writeInt32Impl(uint32_t id, int val); inline void writeInt64Impl(uint32_t id, int64_t val); inline void writeInt32Impl(uint32_t id, int32_t val); inline void writeUint64Impl(uint32_t id, uint64_t val); inline void writeUint32Impl(uint32_t id, uint32_t val); inline void writeFixed64Impl(uint32_t id, uint64_t val); inline void writeFixed32Impl(uint32_t id, uint32_t val); inline void writeSFixed64Impl(uint32_t id, long long val); inline void writeSFixed32Impl(uint32_t id, int val); inline void writeZigzagInt64Impl(uint32_t id, long long val); inline void writeZigzagInt32Impl(uint32_t id, int val); inline void writeSFixed64Impl(uint32_t id, int64_t val); inline void writeSFixed32Impl(uint32_t id, int32_t val); inline void writeZigzagInt64Impl(uint32_t id, int64_t val); inline void writeZigzagInt32Impl(uint32_t id, int32_t val); inline void writeEnumImpl(uint32_t id, int val); inline void writeBoolImpl(uint32_t id, bool val); inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size); Loading @@ -161,6 +162,9 @@ private: bool compact(); size_t editEncodedSize(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 Diff line number Diff line Loading @@ -15,7 +15,8 @@ */ #define LOG_TAG "libprotoutil" #include <inttypes.h> #include <cinttypes> #include <type_traits> #include <android-base/file.h> #include <android/util/protobuf.h> Loading Loading @@ -51,112 +52,73 @@ ProtoOutputStream::clear() mExpectedObjectToken = UINT64_C(-1); } template<typename T> bool ProtoOutputStream::write(uint64_t fieldId, double val) ProtoOutputStream::internalWrite(uint64_t fieldId, T val, const char* typeName) { if (mCompact) return false; 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_INT64: writeInt64Impl(id, (int64_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_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_SFIXED32: writeSFixed32Impl(id, (int32_t)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (int64_t)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int32_t)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: ALOGW("Field type %d is not supported when writing double val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; goto unsupported; } 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 ProtoOutputStream::write(uint64_t fieldId, float val) ProtoOutputStream::write(uint64_t fieldId, double val) { if (mCompact) return false; 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 internalWrite(fieldId, val, "double"); } return true; bool ProtoOutputStream::write(uint64_t fieldId, float val) { return internalWrite(fieldId, val, "float"); } bool ProtoOutputStream::write(uint64_t fieldId, int val) { if (mCompact) return false; 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; return internalWrite(fieldId, val, "int"); } bool ProtoOutputStream::write(uint64_t fieldId, long long val) { if (mCompact) return false; 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; return internalWrite(fieldId, val, "long long"); } bool Loading @@ -169,8 +131,8 @@ ProtoOutputStream::write(uint64_t fieldId, bool val) writeBoolImpl(id, val); return true; default: ALOGW("Field type %d is not supported when writing bool val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); ALOGW("Field type %" PRIu64 " is not supported when writing bool val.", (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; } } Loading @@ -185,8 +147,8 @@ ProtoOutputStream::write(uint64_t fieldId, std::string val) writeUtf8StringImpl(id, val.c_str(), val.size()); return true; default: ALOGW("Field type %d is not supported when writing string val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); ALOGW("Field type %" PRIu64 " is not supported when writing string val.", (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; } } Loading @@ -206,8 +168,8 @@ ProtoOutputStream::write(uint64_t fieldId, const char* val, size_t size) writeMessageBytesImpl(id, val, size); return true; default: ALOGW("Field type %d is not supported when writing char[] val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); ALOGW("Field type %" PRIu64 " is not supported when writing char[] val.", (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; } } Loading Loading @@ -542,17 +504,17 @@ ProtoOutputStream::writeFloatImpl(uint32_t id, float val) } 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.writeRawVarint64((uint64_t)val); mBuffer.writeRawVarint64(val); } inline void ProtoOutputStream::writeInt32Impl(uint32_t id, int val) ProtoOutputStream::writeInt32Impl(uint32_t id, int32_t val) { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint32((uint32_t)val); mBuffer.writeRawVarint32(val); } inline void Loading Loading @@ -584,28 +546,28 @@ ProtoOutputStream::writeFixed32Impl(uint32_t id, uint32_t val) } 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.writeRawFixed64((uint64_t)val); mBuffer.writeRawFixed64(val); } inline void ProtoOutputStream::writeSFixed32Impl(uint32_t id, int val) ProtoOutputStream::writeSFixed32Impl(uint32_t id, int32_t val) { mBuffer.writeHeader(id, WIRE_TYPE_FIXED32); mBuffer.writeRawFixed32((uint32_t)val); mBuffer.writeRawFixed32(val); } 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.writeRawVarint64((val << 1) ^ (val >> 63)); } inline void ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int val) ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int32_t val) { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint32((val << 1) ^ (val >> 31)); Loading libs/protoutil/tests/ProtoOutputStream_test.cpp +25 −3 Original line number Diff line number Diff line Loading @@ -132,17 +132,31 @@ TEST(ProtoOutputStreamTest, Reusability) { EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 15)); EXPECT_EQ(proto.bytesWritten(), 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(); 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) { 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.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('b'); proto.writeRawByte('a'); Loading @@ -168,3 +182,11 @@ TEST(ProtoOutputStreamTest, AdvancedEncoding) { EXPECT_FALSE(log2.has_name()); 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 Diff line number Diff line Loading @@ -17,10 +17,11 @@ #ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H #define ANDROID_UTIL_PROTOOUTPUT_STREAM_H #include <android/util/EncodedBuffer.h> #include <cstdint> #include <string> #include <android/util/EncodedBuffer.h> namespace android { namespace util { Loading Loading @@ -143,16 +144,16 @@ private: inline void writeDoubleImpl(uint32_t id, double val); inline void writeFloatImpl(uint32_t id, float val); inline void writeInt64Impl(uint32_t id, long long val); inline void writeInt32Impl(uint32_t id, int val); inline void writeInt64Impl(uint32_t id, int64_t val); inline void writeInt32Impl(uint32_t id, int32_t val); inline void writeUint64Impl(uint32_t id, uint64_t val); inline void writeUint32Impl(uint32_t id, uint32_t val); inline void writeFixed64Impl(uint32_t id, uint64_t val); inline void writeFixed32Impl(uint32_t id, uint32_t val); inline void writeSFixed64Impl(uint32_t id, long long val); inline void writeSFixed32Impl(uint32_t id, int val); inline void writeZigzagInt64Impl(uint32_t id, long long val); inline void writeZigzagInt32Impl(uint32_t id, int val); inline void writeSFixed64Impl(uint32_t id, int64_t val); inline void writeSFixed32Impl(uint32_t id, int32_t val); inline void writeZigzagInt64Impl(uint32_t id, int64_t val); inline void writeZigzagInt32Impl(uint32_t id, int32_t val); inline void writeEnumImpl(uint32_t id, int val); inline void writeBoolImpl(uint32_t id, bool val); inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size); Loading @@ -161,6 +162,9 @@ private: bool compact(); size_t editEncodedSize(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 Diff line number Diff line Loading @@ -15,7 +15,8 @@ */ #define LOG_TAG "libprotoutil" #include <inttypes.h> #include <cinttypes> #include <type_traits> #include <android-base/file.h> #include <android/util/protobuf.h> Loading Loading @@ -51,112 +52,73 @@ ProtoOutputStream::clear() mExpectedObjectToken = UINT64_C(-1); } template<typename T> bool ProtoOutputStream::write(uint64_t fieldId, double val) ProtoOutputStream::internalWrite(uint64_t fieldId, T val, const char* typeName) { if (mCompact) return false; 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_INT64: writeInt64Impl(id, (int64_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_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_SFIXED32: writeSFixed32Impl(id, (int32_t)val); break; case FIELD_TYPE_SFIXED64: writeSFixed64Impl(id, (int64_t)val); break; case FIELD_TYPE_SINT32: writeZigzagInt32Impl(id, (int32_t)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: ALOGW("Field type %d is not supported when writing double val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); return false; goto unsupported; } 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 ProtoOutputStream::write(uint64_t fieldId, float val) ProtoOutputStream::write(uint64_t fieldId, double val) { if (mCompact) return false; 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 internalWrite(fieldId, val, "double"); } return true; bool ProtoOutputStream::write(uint64_t fieldId, float val) { return internalWrite(fieldId, val, "float"); } bool ProtoOutputStream::write(uint64_t fieldId, int val) { if (mCompact) return false; 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; return internalWrite(fieldId, val, "int"); } bool ProtoOutputStream::write(uint64_t fieldId, long long val) { if (mCompact) return false; 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; return internalWrite(fieldId, val, "long long"); } bool Loading @@ -169,8 +131,8 @@ ProtoOutputStream::write(uint64_t fieldId, bool val) writeBoolImpl(id, val); return true; default: ALOGW("Field type %d is not supported when writing bool val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); ALOGW("Field type %" PRIu64 " is not supported when writing bool val.", (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; } } Loading @@ -185,8 +147,8 @@ ProtoOutputStream::write(uint64_t fieldId, std::string val) writeUtf8StringImpl(id, val.c_str(), val.size()); return true; default: ALOGW("Field type %d is not supported when writing string val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); ALOGW("Field type %" PRIu64 " is not supported when writing string val.", (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; } } Loading @@ -206,8 +168,8 @@ ProtoOutputStream::write(uint64_t fieldId, const char* val, size_t size) writeMessageBytesImpl(id, val, size); return true; default: ALOGW("Field type %d is not supported when writing char[] val.", (int)((fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT)); ALOGW("Field type %" PRIu64 " is not supported when writing char[] val.", (fieldId & FIELD_TYPE_MASK) >> FIELD_TYPE_SHIFT); return false; } } Loading Loading @@ -542,17 +504,17 @@ ProtoOutputStream::writeFloatImpl(uint32_t id, float val) } 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.writeRawVarint64((uint64_t)val); mBuffer.writeRawVarint64(val); } inline void ProtoOutputStream::writeInt32Impl(uint32_t id, int val) ProtoOutputStream::writeInt32Impl(uint32_t id, int32_t val) { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint32((uint32_t)val); mBuffer.writeRawVarint32(val); } inline void Loading Loading @@ -584,28 +546,28 @@ ProtoOutputStream::writeFixed32Impl(uint32_t id, uint32_t val) } 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.writeRawFixed64((uint64_t)val); mBuffer.writeRawFixed64(val); } inline void ProtoOutputStream::writeSFixed32Impl(uint32_t id, int val) ProtoOutputStream::writeSFixed32Impl(uint32_t id, int32_t val) { mBuffer.writeHeader(id, WIRE_TYPE_FIXED32); mBuffer.writeRawFixed32((uint32_t)val); mBuffer.writeRawFixed32(val); } 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.writeRawVarint64((val << 1) ^ (val >> 63)); } inline void ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int val) ProtoOutputStream::writeZigzagInt32Impl(uint32_t id, int32_t val) { mBuffer.writeHeader(id, WIRE_TYPE_VARINT); mBuffer.writeRawVarint32((val << 1) ^ (val >> 31)); Loading
libs/protoutil/tests/ProtoOutputStream_test.cpp +25 −3 Original line number Diff line number Diff line Loading @@ -132,17 +132,31 @@ TEST(ProtoOutputStreamTest, Reusability) { EXPECT_TRUE(proto.write(FIELD_TYPE_INT32 | ComplexProto::kIntsFieldNumber, 15)); EXPECT_EQ(proto.bytesWritten(), 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(); 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) { 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.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('b'); proto.writeRawByte('a'); Loading @@ -168,3 +182,11 @@ TEST(ProtoOutputStreamTest, AdvancedEncoding) { EXPECT_FALSE(log2.has_name()); 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