• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2014 The gRPC Authors
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 
17 package io.grpc.protobuf.nano;
18 
19 import com.google.protobuf.nano.CodedOutputByteBufferNano;
20 import com.google.protobuf.nano.MessageNano;
21 import io.grpc.KnownLength;
22 import java.io.ByteArrayInputStream;
23 import java.io.IOException;
24 import java.io.InputStream;
25 import javax.annotation.Nullable;
26 
27 /**
28  * An {@link InputStream} backed by a nano proto.
29  */
30 final class NanoProtoInputStream extends InputStream implements KnownLength {
31 
32   // NanoProtoInputStream is first initialized with a *message*. *partial* is initially null.
33   // Once there has been a read operation on this stream, *message* is serialized to *partial* and
34   // set to null.
35   @Nullable private MessageNano message;
36   @Nullable private ByteArrayInputStream partial;
37 
NanoProtoInputStream(MessageNano message)38   NanoProtoInputStream(MessageNano message) {
39     this.message = message;
40   }
41 
toPartial()42   private void toPartial() {
43     if (message != null) {
44       partial = new ByteArrayInputStream(MessageNano.toByteArray(message));
45       message = null;
46     }
47   }
48 
49   @Override
read()50   public int read() throws IOException {
51     toPartial();
52     if (partial != null) {
53       return partial.read();
54     }
55     return -1;
56   }
57 
58   @Override
read(byte[] b, int off, int len)59   public int read(byte[] b, int off, int len) throws IOException {
60     if (message != null) {
61       int size = message.getSerializedSize();
62       if (size == 0) {
63         message = null;
64         partial = null;
65         return -1;
66       }
67       if (len >= size) {
68         // This is the only case that is zero-copy.
69         CodedOutputByteBufferNano output = CodedOutputByteBufferNano.newInstance(b, off, size);
70         message.writeTo(output);
71         output.checkNoSpaceLeft();
72 
73         message = null;
74         partial = null;
75         return size;
76       }
77 
78       toPartial();
79     }
80     if (partial != null) {
81       return partial.read(b, off, len);
82     }
83     return -1;
84   }
85 
86   @Override
available()87   public int available() {
88     if (message != null) {
89       return message.getSerializedSize();
90     } else if (partial != null) {
91       return partial.available();
92     }
93     return 0;
94   }
95 }
96