1974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin/* 2974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Copyright (C) 2017 The Android Open Source Project 3974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * 4974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Licensed under the Apache License, Version 2.0 (the "License"); 5974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * you may not use this file except in compliance with the License. 6974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * You may obtain a copy of the License at 7974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * 8974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * http://www.apache.org/licenses/LICENSE-2.0 9974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * 10974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Unless required by applicable law or agreed to in writing, software 11974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * distributed under the License is distributed on an "AS IS" BASIS, 12974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * See the License for the specific language governing permissions and 14974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * limitations under the License. 15974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 16974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 17974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin#ifndef ANDROID_UTIL_PROTOOUTPUT_STREAM_H 18974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin#define ANDROID_UTIL_PROTOOUTPUT_STREAM_H 19974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 20974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin#include <android/util/EncodedBuffer.h> 21974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 22974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin#include <string> 23974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 24974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinnamespace android { 25974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinnamespace util { 26974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 27974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin/** 285ee0787024cc446a21008ff5710dec19c6afc834Yi Jin * Position of the field type in a 64-bits fieldId. 2904625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin */ 3004625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_SHIFT = 32; 3104625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin 3204625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin/** 3304625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin * Mask for the field types stored in a fieldId. Leaves a whole 3404625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin * byte for future expansion, even though there are currently only 17 types. 3504625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin */ 3604625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_MASK = 0x0ffULL << FIELD_TYPE_SHIFT; 3704625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin 38f9ed04b3d938b06329fcd14d4f2b461000d028daYi Jin/** 39f9ed04b3d938b06329fcd14d4f2b461000d028daYi Jin * The types are copied from external/protobuf/src/google/protobuf/descriptor.h directly, 40f9ed04b3d938b06329fcd14d4f2b461000d028daYi Jin * so no extra mapping needs to be maintained in this case. 41f9ed04b3d938b06329fcd14d4f2b461000d028daYi Jin */ 4204625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_UNKNOWN = 0; 4304625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_DOUBLE = 1ULL << FIELD_TYPE_SHIFT; // double, exactly eight bytes on the wire. 4404625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_FLOAT = 2ULL << FIELD_TYPE_SHIFT; // float, exactly four bytes on the wire. 4504625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_INT64 = 3ULL << FIELD_TYPE_SHIFT; // int64, varint on the wire. Negative numbers 4604625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin // take 10 bytes. Use TYPE_SINT64 if negative 4704625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin // values are likely. 4804625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_UINT64 = 4ULL << FIELD_TYPE_SHIFT; // uint64, varint on the wire. 4904625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_INT32 = 5ULL << FIELD_TYPE_SHIFT; // int32, varint on the wire. Negative numbers 5004625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin // take 10 bytes. Use TYPE_SINT32 if negative 5104625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin // values are likely. 5204625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_FIXED64 = 6ULL << FIELD_TYPE_SHIFT; // uint64, exactly eight bytes on the wire. 5304625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_FIXED32 = 7ULL << FIELD_TYPE_SHIFT; // uint32, exactly four bytes on the wire. 5404625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_BOOL = 8ULL << FIELD_TYPE_SHIFT; // bool, varint on the wire. 5504625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_STRING = 9ULL << FIELD_TYPE_SHIFT; // UTF-8 text. 56f9ed04b3d938b06329fcd14d4f2b461000d028daYi Jin// const uint64_t FIELD_TYPE_GROUP = 10ULL << FIELD_TYPE_SHIFT; // Tag-delimited message. Deprecated. 5704625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_MESSAGE = 11ULL << FIELD_TYPE_SHIFT; // Length-delimited message. 5804625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin 5904625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_BYTES = 12ULL << FIELD_TYPE_SHIFT; // Arbitrary byte array. 6004625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_UINT32 = 13ULL << FIELD_TYPE_SHIFT; // uint32, varint on the wire 6104625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_ENUM = 14ULL << FIELD_TYPE_SHIFT; // Enum, varint on the wire 6204625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_SFIXED32 = 15ULL << FIELD_TYPE_SHIFT; // int32, exactly four bytes on the wire 6304625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_SFIXED64 = 16ULL << FIELD_TYPE_SHIFT; // int64, exactly eight bytes on the wire 6404625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_SINT32 = 17ULL << FIELD_TYPE_SHIFT; // int32, ZigZag-encoded varint on the wire 6504625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_TYPE_SINT64 = 18ULL << FIELD_TYPE_SHIFT; // int64, ZigZag-encoded varint on the wire 6604625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin 6704625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin// 6804625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin// FieldId flags for whether the field is single, repeated or packed. 6904625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin// TODO: packed is not supported yet. 7004625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin// 7104625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_COUNT_SHIFT = 40; 7204625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_COUNT_MASK = 0x0fULL << FIELD_COUNT_SHIFT; 7304625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_COUNT_UNKNOWN = 0; 7404625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_COUNT_SINGLE = 1ULL << FIELD_COUNT_SHIFT; 7504625ad4886a478bf74bbfc13937c10fa63eb272Yi Jinconst uint64_t FIELD_COUNT_REPEATED = 2ULL << FIELD_COUNT_SHIFT; 76f9ed04b3d938b06329fcd14d4f2b461000d028daYi Jinconst uint64_t FIELD_COUNT_PACKED = 5ULL << FIELD_COUNT_SHIFT; 7704625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin 7804625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin/** 79974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Class to write to a protobuf stream. 80974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * 81974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Each write method takes an ID code from the protoc generated classes 82974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * and the value to write. To make a nested object, call start 83974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * and then end when you are done. 84974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * 85974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * See the java version implementation (ProtoOutputStream.java) for more infos. 86974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 87974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinclass ProtoOutputStream 88974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin{ 89974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinpublic: 9042711a0b4fffd0dc670ec7bc38cc7f954c60e530Yi Jin ProtoOutputStream(); 91974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin ~ProtoOutputStream(); 92974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 93974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 94974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Write APIs for dumping protobuf data. Returns true if the write succeeds. 95974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 96974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool write(uint64_t fieldId, double val); 97974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool write(uint64_t fieldId, float val); 98974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool write(uint64_t fieldId, int val); 99974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool write(uint64_t fieldId, long long val); 100974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool write(uint64_t fieldId, bool val); 101974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool write(uint64_t fieldId, std::string val); 102e08333067a9f4ce9176dff490c4b163f71f56e1eYi Jin bool write(uint64_t fieldId, const char* val, size_t size); 103974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 104974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 105974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Starts a sub-message write session. 106974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Returns a token of this write session. 107974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin * Must call end(token) when finish write this sub-message. 108974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 1095ee0787024cc446a21008ff5710dec19c6afc834Yi Jin uint64_t start(uint64_t fieldId); 1105ee0787024cc446a21008ff5710dec19c6afc834Yi Jin void end(uint64_t token); 111974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 112974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin /** 1130abdfb0889a4957faaba8a95903e529fced7316cYi Jin * Returns how many bytes are buffered in ProtoOutputStream. 1140abdfb0889a4957faaba8a95903e529fced7316cYi Jin * Notice, this is not the actual(compact) size of the output data. 1150abdfb0889a4957faaba8a95903e529fced7316cYi Jin */ 1160abdfb0889a4957faaba8a95903e529fced7316cYi Jin size_t bytesWritten(); 1170abdfb0889a4957faaba8a95903e529fced7316cYi Jin 1180abdfb0889a4957faaba8a95903e529fced7316cYi Jin /** 11904625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin * Flushes the protobuf data out to given fd. When the following functions are called, 12004625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin * it is not able to write to ProtoOutputStream any more since the data is compact. 121974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin */ 12204625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin size_t size(); // Get the size of the serialized protobuf. 12304625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin EncodedBuffer::iterator data(); // Get the reader apis of the data. 12404625ad4886a478bf74bbfc13937c10fa63eb272Yi Jin bool flush(int fd); // Flush data directly to a file descriptor. 12542711a0b4fffd0dc670ec7bc38cc7f954c60e530Yi Jin 1267f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin /** 1277f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin * Clears the ProtoOutputStream so the buffer can be reused instead of deallocation/allocation again. 1287f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin */ 1297f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin void clear(); 1307f9e63b63269baa41a36fc31acd6fc071309c26cYi Jin 1318ad193870b2f8d6f8478d591ced2100e22b23229Yi Jin // Please don't use the following functions to dump protos unless you are familiar with protobuf encoding. 13242711a0b4fffd0dc670ec7bc38cc7f954c60e530Yi Jin void writeRawVarint(uint64_t varint); 13342711a0b4fffd0dc670ec7bc38cc7f954c60e530Yi Jin void writeLengthDelimitedHeader(uint32_t id, size_t size); 13442711a0b4fffd0dc670ec7bc38cc7f954c60e530Yi Jin void writeRawByte(uint8_t byte); 135974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 136974a9c28853d24ff94f000ae9f5c816d9538897bYi Jinprivate: 137974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin EncodedBuffer mBuffer; 138974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin size_t mCopyBegin; 139974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool mCompact; 14000a754499e125c56ed6fae7b9d4eedb6ac7922a8Yi Jin uint32_t mDepth; 14100a754499e125c56ed6fae7b9d4eedb6ac7922a8Yi Jin uint32_t mObjectId; 1425ee0787024cc446a21008ff5710dec19c6afc834Yi Jin uint64_t mExpectedObjectToken; 143974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 144974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeDoubleImpl(uint32_t id, double val); 145974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeFloatImpl(uint32_t id, float val); 146974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeInt64Impl(uint32_t id, long long val); 147974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeInt32Impl(uint32_t id, int val); 148974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeUint64Impl(uint32_t id, uint64_t val); 149974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeUint32Impl(uint32_t id, uint32_t val); 150974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeFixed64Impl(uint32_t id, uint64_t val); 151974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeFixed32Impl(uint32_t id, uint32_t val); 152974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeSFixed64Impl(uint32_t id, long long val); 153974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeSFixed32Impl(uint32_t id, int val); 154974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeZigzagInt64Impl(uint32_t id, long long val); 155974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeZigzagInt32Impl(uint32_t id, int val); 156974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeEnumImpl(uint32_t id, int val); 157974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeBoolImpl(uint32_t id, bool val); 158974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin inline void writeUtf8StringImpl(uint32_t id, const char* val, size_t size); 1598ad193870b2f8d6f8478d591ced2100e22b23229Yi Jin inline void writeMessageBytesImpl(uint32_t id, const char* val, size_t size); 160974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 161974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool compact(); 162974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin size_t editEncodedSize(size_t rawSize); 163974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin bool compactSize(size_t rawSize); 164974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin}; 165974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 166974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin} 167974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin} 168974a9c28853d24ff94f000ae9f5c816d9538897bYi Jin 169e08333067a9f4ce9176dff490c4b163f71f56e1eYi Jin#endif // ANDROID_UTIL_PROTOOUTPUT_STREAM_H 170