1 /*
2  * Copyright(C) 2017 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0(the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http:  // www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  *distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 #include "VtsProfilingUtil.h"
17 
18 #include <stdint.h>
19 
20 #include "google/protobuf/io/coded_stream.h"
21 
22 namespace android {
23 namespace vts {
24 
writeOneDelimited(const google::protobuf::MessageLite & message,google::protobuf::io::ZeroCopyOutputStream * out)25 bool writeOneDelimited(const google::protobuf::MessageLite& message,
26                        google::protobuf::io::ZeroCopyOutputStream* out) {
27   // We create a new coded stream for each message. This is fast.
28   google::protobuf::io::CodedOutputStream output(out);
29 
30   // Write the size.
31   const int size = message.ByteSize();
32   output.WriteVarint32(size);
33 
34   uint8_t* buffer = output.GetDirectBufferForNBytesAndAdvance(size);
35   if (buffer) {
36     // Optimization: The message fits in one buffer, so use the faster
37     // direct-to-array serialization path.
38     message.SerializeWithCachedSizesToArray(buffer);
39   } else {
40     // Slightly-slower path when the message is multiple buffers.
41     message.SerializeWithCachedSizes(&output);
42     if (output.HadError()) {
43       return false;
44     }
45   }
46 
47   return true;
48 }
49 
readOneDelimited(google::protobuf::MessageLite * message,google::protobuf::io::ZeroCopyInputStream * in)50 bool readOneDelimited(google::protobuf::MessageLite* message,
51                       google::protobuf::io::ZeroCopyInputStream* in) {
52   // We create a new coded stream for each message. This is fast,
53   // and it makes sure the 64MB total size limit is imposed per-message rather
54   // than on the whole stream (See the CodedInputStream interface for more
55   // info on this limit).
56   google::protobuf::io::CodedInputStream input(in);
57 
58   // Read the size.
59   uint32_t size;
60   if (!input.ReadVarint32(&size)) {
61     return false;
62   }
63   // Tell the stream not to read beyond that size.
64   const auto limit = input.PushLimit(size);
65 
66   // Parse the message.
67   if (!message->MergeFromCodedStream(&input)) {
68     return false;
69   }
70   if (!input.ConsumedEntireMessage()) {
71     return false;
72   }
73 
74   // Release the limit.
75   input.PopLimit(limit);
76 
77   return true;
78 }
79 
80 }  // namespace vts
81 }  // namespace android
82