Implement go/streaming-proto native libs, part 2
Implement ProtoOutputStream.h to write protobuf format data.
Usage of dumping proto:
ProtoOutputStream proto(fd);
proto.write(fieldId, value1); // dump a single value
// start to dump a message:
long long token = proto.start(messageFieldId);
proto.write(nestedField1, nestedValue1);
...
proto.end(token);
fieldId will be generated by protoc-cpp plugin(TBD). It is an encoded uint64_t
value, with 0 - 32 bits as its proto number, 33 - 40 bits reserved for
field type, int32, bool, string, message, etc. and 41 - 43 bits for
single, repeated or packed type. Currently packed field is not
supported.
Bug: 65641021
Test: N/A, need to wait for protoc-cpp plugin and will test in
incident_helper
Change-Id: Ic188615b950235aae0edeee4876b78d31feb5619
diff --git a/libs/protoutil/include/android/util/ProtoOutputStream.h b/libs/protoutil/include/android/util/ProtoOutputStream.h
new file mode 100644
index 0000000..49ec169
--- /dev/null
+++ b/libs/protoutil/include/android/util/ProtoOutputStream.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H
+#define ANDROID_UTIL_PROTOOUTPUT_STREAM_H
+
+#include <android/util/EncodedBuffer.h>
+
+#include <stdint.h>
+#include <string>
+
+namespace android {
+namespace util {
+
+/**
+ * Class to write to a protobuf stream.
+ *
+ * Each write method takes an ID code from the protoc generated classes
+ * and the value to write. To make a nested object, call start
+ * and then end when you are done.
+ *
+ * See the java version implementation (ProtoOutputStream.java) for more infos.
+ */
+class ProtoOutputStream
+{
+public:
+ ProtoOutputStream(int fd);
+ ~ProtoOutputStream();
+
+ /**
+ * Write APIs for dumping protobuf data. Returns true if the write succeeds.
+ */
+ bool write(uint64_t fieldId, double val);
+ bool write(uint64_t fieldId, float val);
+ bool write(uint64_t fieldId, int val);
+ bool write(uint64_t fieldId, long long val);
+ bool write(uint64_t fieldId, bool val);
+ bool write(uint64_t fieldId, std::string val);
+ bool write(uint64_t fieldId, const char* val);
+
+ /**
+ * Starts a sub-message write session.
+ * Returns a token of this write session.
+ * Must call end(token) when finish write this sub-message.
+ */
+ long long start(uint64_t fieldId);
+ void end(long long token);
+
+ /**
+ * Flushes the protobuf data out.
+ */
+ bool flush();
+
+private:
+ EncodedBuffer mBuffer;
+ int mFd;
+ size_t mCopyBegin;
+ bool mCompact;
+ int mDepth;
+ int mObjectId;
+ long long mExpectedObjectToken;
+
+ 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 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 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);
+
+ bool compact();
+ size_t editEncodedSize(size_t rawSize);
+ bool compactSize(size_t rawSize);
+};
+
+}
+}
+
+#endif // ANDROID_UTIL_PROTOOUTPUT_STREAM_H
\ No newline at end of file