| khenaidoo | 0927c72 | 2021-12-15 16:49:32 -0500 | [diff] [blame] | 1 | package codec |
| 2 | |
| 3 | import ( |
| 4 | "io" |
| 5 | |
| 6 | "github.com/golang/protobuf/proto" |
| Abhay Kumar | 40252eb | 2025-10-13 13:25:53 +0000 | [diff] [blame^] | 7 | |
| khenaidoo | 0927c72 | 2021-12-15 16:49:32 -0500 | [diff] [blame] | 8 | "github.com/jhump/protoreflect/internal/codec" |
| 9 | ) |
| 10 | |
| 11 | // ErrOverflow is returned when an integer is too large to be represented. |
| 12 | var ErrOverflow = codec.ErrOverflow |
| 13 | |
| 14 | // ErrBadWireType is returned when decoding a wire-type from a buffer that |
| 15 | // is not valid. |
| 16 | var ErrBadWireType = codec.ErrBadWireType |
| 17 | |
| 18 | // NB: much of the implementation is in an internal package, to avoid an import |
| 19 | // cycle between this codec package and the desc package. We export it from |
| 20 | // this package, but we can't use a type alias because we also need to add |
| 21 | // methods to it, to broaden the exposed API. |
| 22 | |
| 23 | // Buffer is a reader and a writer that wraps a slice of bytes and also |
| 24 | // provides API for decoding and encoding the protobuf binary format. |
| 25 | // |
| 26 | // Its operation is similar to that of a bytes.Buffer: writing pushes |
| 27 | // data to the end of the buffer while reading pops data from the head |
| 28 | // of the buffer. So the same buffer can be used to both read and write. |
| 29 | type Buffer codec.Buffer |
| 30 | |
| 31 | // NewBuffer creates a new buffer with the given slice of bytes as the |
| 32 | // buffer's initial contents. |
| 33 | func NewBuffer(buf []byte) *Buffer { |
| 34 | return (*Buffer)(codec.NewBuffer(buf)) |
| 35 | } |
| 36 | |
| 37 | // SetDeterministic sets this buffer to encode messages deterministically. This |
| 38 | // is useful for tests. But the overhead is non-zero, so it should not likely be |
| 39 | // used outside of tests. When true, map fields in a message must have their |
| 40 | // keys sorted before serialization to ensure deterministic output. Otherwise, |
| 41 | // values in a map field will be serialized in map iteration order. |
| 42 | func (cb *Buffer) SetDeterministic(deterministic bool) { |
| 43 | (*codec.Buffer)(cb).SetDeterministic(deterministic) |
| 44 | } |
| 45 | |
| 46 | // IsDeterministic returns whether or not this buffer is configured to encode |
| 47 | // messages deterministically. |
| 48 | func (cb *Buffer) IsDeterministic() bool { |
| 49 | return (*codec.Buffer)(cb).IsDeterministic() |
| 50 | } |
| 51 | |
| 52 | // Reset resets this buffer back to empty. Any subsequent writes/encodes |
| 53 | // to the buffer will allocate a new backing slice of bytes. |
| 54 | func (cb *Buffer) Reset() { |
| 55 | (*codec.Buffer)(cb).Reset() |
| 56 | } |
| 57 | |
| 58 | // Bytes returns the slice of bytes remaining in the buffer. Note that |
| 59 | // this does not perform a copy: if the contents of the returned slice |
| 60 | // are modified, the modifications will be visible to subsequent reads |
| 61 | // via the buffer. |
| 62 | func (cb *Buffer) Bytes() []byte { |
| 63 | return (*codec.Buffer)(cb).Bytes() |
| 64 | } |
| 65 | |
| 66 | // String returns the remaining bytes in the buffer as a string. |
| 67 | func (cb *Buffer) String() string { |
| 68 | return (*codec.Buffer)(cb).String() |
| 69 | } |
| 70 | |
| 71 | // EOF returns true if there are no more bytes remaining to read. |
| 72 | func (cb *Buffer) EOF() bool { |
| 73 | return (*codec.Buffer)(cb).EOF() |
| 74 | } |
| 75 | |
| 76 | // Skip attempts to skip the given number of bytes in the input. If |
| 77 | // the input has fewer bytes than the given count, io.ErrUnexpectedEOF |
| 78 | // is returned and the buffer is unchanged. Otherwise, the given number |
| 79 | // of bytes are skipped and nil is returned. |
| 80 | func (cb *Buffer) Skip(count int) error { |
| 81 | return (*codec.Buffer)(cb).Skip(count) |
| 82 | |
| 83 | } |
| 84 | |
| 85 | // Len returns the remaining number of bytes in the buffer. |
| 86 | func (cb *Buffer) Len() int { |
| 87 | return (*codec.Buffer)(cb).Len() |
| 88 | } |
| 89 | |
| 90 | // Read implements the io.Reader interface. If there are no bytes |
| 91 | // remaining in the buffer, it will return 0, io.EOF. Otherwise, |
| 92 | // it reads max(len(dest), cb.Len()) bytes from input and copies |
| 93 | // them into dest. It returns the number of bytes copied and a nil |
| 94 | // error in this case. |
| 95 | func (cb *Buffer) Read(dest []byte) (int, error) { |
| 96 | return (*codec.Buffer)(cb).Read(dest) |
| 97 | } |
| 98 | |
| 99 | var _ io.Reader = (*Buffer)(nil) |
| 100 | |
| 101 | // Write implements the io.Writer interface. It always returns |
| 102 | // len(data), nil. |
| 103 | func (cb *Buffer) Write(data []byte) (int, error) { |
| 104 | return (*codec.Buffer)(cb).Write(data) |
| 105 | } |
| 106 | |
| 107 | var _ io.Writer = (*Buffer)(nil) |
| 108 | |
| 109 | // DecodeVarint reads a varint-encoded integer from the Buffer. |
| 110 | // This is the format for the |
| 111 | // int32, int64, uint32, uint64, bool, and enum |
| 112 | // protocol buffer types. |
| 113 | func (cb *Buffer) DecodeVarint() (uint64, error) { |
| 114 | return (*codec.Buffer)(cb).DecodeVarint() |
| 115 | } |
| 116 | |
| 117 | // DecodeTagAndWireType decodes a field tag and wire type from input. |
| 118 | // This reads a varint and then extracts the two fields from the varint |
| 119 | // value read. |
| 120 | func (cb *Buffer) DecodeTagAndWireType() (tag int32, wireType int8, err error) { |
| 121 | return (*codec.Buffer)(cb).DecodeTagAndWireType() |
| 122 | } |
| 123 | |
| 124 | // DecodeFixed64 reads a 64-bit integer from the Buffer. |
| 125 | // This is the format for the |
| 126 | // fixed64, sfixed64, and double protocol buffer types. |
| 127 | func (cb *Buffer) DecodeFixed64() (x uint64, err error) { |
| 128 | return (*codec.Buffer)(cb).DecodeFixed64() |
| 129 | } |
| 130 | |
| 131 | // DecodeFixed32 reads a 32-bit integer from the Buffer. |
| 132 | // This is the format for the |
| 133 | // fixed32, sfixed32, and float protocol buffer types. |
| 134 | func (cb *Buffer) DecodeFixed32() (x uint64, err error) { |
| 135 | return (*codec.Buffer)(cb).DecodeFixed32() |
| 136 | } |
| 137 | |
| 138 | // DecodeRawBytes reads a count-delimited byte buffer from the Buffer. |
| 139 | // This is the format used for the bytes protocol buffer |
| 140 | // type and for embedded messages. |
| 141 | func (cb *Buffer) DecodeRawBytes(alloc bool) (buf []byte, err error) { |
| 142 | return (*codec.Buffer)(cb).DecodeRawBytes(alloc) |
| 143 | } |
| 144 | |
| 145 | // ReadGroup reads the input until a "group end" tag is found |
| 146 | // and returns the data up to that point. Subsequent reads from |
| 147 | // the buffer will read data after the group end tag. If alloc |
| 148 | // is true, the data is copied to a new slice before being returned. |
| 149 | // Otherwise, the returned slice is a view into the buffer's |
| 150 | // underlying byte slice. |
| 151 | // |
| 152 | // This function correctly handles nested groups: if a "group start" |
| 153 | // tag is found, then that group's end tag will be included in the |
| 154 | // returned data. |
| 155 | func (cb *Buffer) ReadGroup(alloc bool) ([]byte, error) { |
| 156 | return (*codec.Buffer)(cb).ReadGroup(alloc) |
| 157 | } |
| 158 | |
| 159 | // SkipGroup is like ReadGroup, except that it discards the |
| 160 | // data and just advances the buffer to point to the input |
| 161 | // right *after* the "group end" tag. |
| 162 | func (cb *Buffer) SkipGroup() error { |
| 163 | return (*codec.Buffer)(cb).SkipGroup() |
| 164 | } |
| 165 | |
| 166 | // SkipField attempts to skip the value of a field with the given wire |
| 167 | // type. When consuming a protobuf-encoded stream, it can be called immediately |
| 168 | // after DecodeTagAndWireType to discard the subsequent data for the field. |
| 169 | func (cb *Buffer) SkipField(wireType int8) error { |
| 170 | return (*codec.Buffer)(cb).SkipField(wireType) |
| 171 | } |
| 172 | |
| 173 | // EncodeVarint writes a varint-encoded integer to the Buffer. |
| 174 | // This is the format for the |
| 175 | // int32, int64, uint32, uint64, bool, and enum |
| 176 | // protocol buffer types. |
| 177 | func (cb *Buffer) EncodeVarint(x uint64) error { |
| 178 | return (*codec.Buffer)(cb).EncodeVarint(x) |
| 179 | } |
| 180 | |
| 181 | // EncodeTagAndWireType encodes the given field tag and wire type to the |
| 182 | // buffer. This combines the two values and then writes them as a varint. |
| 183 | func (cb *Buffer) EncodeTagAndWireType(tag int32, wireType int8) error { |
| 184 | return (*codec.Buffer)(cb).EncodeTagAndWireType(tag, wireType) |
| 185 | } |
| 186 | |
| 187 | // EncodeFixed64 writes a 64-bit integer to the Buffer. |
| 188 | // This is the format for the |
| 189 | // fixed64, sfixed64, and double protocol buffer types. |
| 190 | func (cb *Buffer) EncodeFixed64(x uint64) error { |
| 191 | return (*codec.Buffer)(cb).EncodeFixed64(x) |
| 192 | |
| 193 | } |
| 194 | |
| 195 | // EncodeFixed32 writes a 32-bit integer to the Buffer. |
| 196 | // This is the format for the |
| 197 | // fixed32, sfixed32, and float protocol buffer types. |
| 198 | func (cb *Buffer) EncodeFixed32(x uint64) error { |
| 199 | return (*codec.Buffer)(cb).EncodeFixed32(x) |
| 200 | } |
| 201 | |
| 202 | // EncodeRawBytes writes a count-delimited byte buffer to the Buffer. |
| 203 | // This is the format used for the bytes protocol buffer |
| 204 | // type and for embedded messages. |
| 205 | func (cb *Buffer) EncodeRawBytes(b []byte) error { |
| 206 | return (*codec.Buffer)(cb).EncodeRawBytes(b) |
| 207 | } |
| 208 | |
| 209 | // EncodeMessage writes the given message to the buffer. |
| 210 | func (cb *Buffer) EncodeMessage(pm proto.Message) error { |
| 211 | return (*codec.Buffer)(cb).EncodeMessage(pm) |
| 212 | } |
| 213 | |
| 214 | // EncodeDelimitedMessage writes the given message to the buffer with a |
| 215 | // varint-encoded length prefix (the delimiter). |
| 216 | func (cb *Buffer) EncodeDelimitedMessage(pm proto.Message) error { |
| 217 | return (*codec.Buffer)(cb).EncodeDelimitedMessage(pm) |
| 218 | } |