diff options
Diffstat (limited to 'libs/protoutil/src/ProtoOutputStream.cpp')
-rw-r--r-- | libs/protoutil/src/ProtoOutputStream.cpp | 174 |
1 files changed, 63 insertions, 111 deletions
diff --git a/libs/protoutil/src/ProtoOutputStream.cpp b/libs/protoutil/src/ProtoOutputStream.cpp index 22b9709ef066..ff3fad6055e1 100644 --- a/libs/protoutil/src/ProtoOutputStream.cpp +++ b/libs/protoutil/src/ProtoOutputStream.cpp @@ -15,8 +15,10 @@ */ #define LOG_TAG "libprotoutil" -#include <inttypes.h> +#include <cinttypes> +#include <type_traits> +#include <android-base/file.h> #include <android/util/protobuf.h> #include <android/util/ProtoOutputStream.h> #include <cutils/log.h> @@ -50,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, double val) +{ + return internalWrite(fieldId, val, "double"); } + bool ProtoOutputStream::write(uint64_t fieldId, float 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 true; + 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 @@ -168,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; } } @@ -184,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; } } @@ -205,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; } } @@ -281,12 +244,14 @@ ProtoOutputStream::end(uint64_t token) { if (token != mExpectedObjectToken) { ALOGE("Unexpected token: 0x%" PRIx64 ", should be 0x%" PRIx64, token, mExpectedObjectToken); + mDepth = UINT32_C(-1); // make depth invalid return; } uint32_t depth = getDepthFromToken(token); if (depth != (mDepth & 0x01ff)) { ALOGE("Unexpected depth: %" PRIu32 ", should be %" PRIu32, depth, mDepth); + mDepth = UINT32_C(-1); // make depth invalid return; } mDepth--; @@ -319,7 +284,7 @@ bool ProtoOutputStream::compact() { if (mCompact) return true; if (mDepth != 0) { - ALOGE("Can't compact when depth(%" PRIu32 ") is not zero. Missing calls to end.", mDepth); + ALOGE("Can't compact when depth(%" PRIu32 ") is not zero. Missing or extra calls to end.", mDepth); return false; } // record the size of the original buffer. @@ -462,24 +427,11 @@ ProtoOutputStream::size() { if (!compact()) { ALOGE("compact failed, the ProtoOutputStream data is corrupted!"); - // TODO: handle this error + return 0; } return mBuffer.size(); } -static bool write_all(int fd, uint8_t const* buf, size_t size) -{ - while (size > 0) { - ssize_t amt = ::write(fd, buf, size); - if (amt < 0) { - return false; - } - size -= amt; - buf += amt; - } - return true; -} - bool ProtoOutputStream::flush(int fd) { @@ -488,7 +440,7 @@ ProtoOutputStream::flush(int fd) EncodedBuffer::iterator it = mBuffer.begin(); while (it.readBuffer() != NULL) { - if (!write_all(fd, it.readBuffer(), it.currentToRead())) return false; + if (!android::base::WriteFully(fd, it.readBuffer(), it.currentToRead())) return false; it.rp()->move(it.currentToRead()); } return true; @@ -499,7 +451,7 @@ ProtoOutputStream::data() { if (!compact()) { ALOGE("compact failed, the ProtoOutputStream data is corrupted!"); - // TODO: handle this error + mBuffer.clear(); } return mBuffer.begin(); } @@ -554,17 +506,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 @@ -596,28 +548,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)); |