summaryrefslogtreecommitdiff
path: root/libs/protoutil/src/ProtoOutputStream.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/protoutil/src/ProtoOutputStream.cpp')
-rw-r--r--libs/protoutil/src/ProtoOutputStream.cpp174
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));