1 /*
2 * Copyright 2016 The Netty Project
3 *
4 * The Netty Project licenses this file to you under the Apache License, version 2.0 (the
5 * "License"); you may not use this file except in compliance with the License. You may obtain a
6 * copy of the License at:
7 *
8 * https://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software distributed under the License
11 * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 * or implied. See the License for the specific language governing permissions and limitations under
13 * the License.
14 */
15
16 package io.netty.handler.codec.redis;
17
18 import io.netty.buffer.ByteBuf;
19 import io.netty.util.internal.UnstableApi;
20
21 /**
22 * Type of <a href="https://redis.io/topics/protocol">RESP (REdis Serialization Protocol)</a>.
23 */
24 @UnstableApi
25 public enum RedisMessageType {
26
27 INLINE_COMMAND(null, true),
28 SIMPLE_STRING((byte) '+', true),
29 ERROR((byte) '-', true),
30 INTEGER((byte) ':', true),
31 BULK_STRING((byte) '$', false),
32 ARRAY_HEADER((byte) '*', false);
33
34 private final Byte value;
35 private final boolean inline;
36
37 RedisMessageType(Byte value, boolean inline) {
38 this.value = value;
39 this.inline = inline;
40 }
41
42 /**
43 * Returns length of this type.
44 */
45 public int length() {
46 return value != null ? RedisConstants.TYPE_LENGTH : 0;
47 }
48
49 /**
50 * Returns {@code true} if this type is inline type, or returns {@code false}. If this is {@code true},
51 * this type doesn't have length field.
52 */
53 public boolean isInline() {
54 return inline;
55 }
56
57 /**
58 * Determine {@link RedisMessageType} based on the type prefix {@code byte} read from given the buffer.
59 */
60 public static RedisMessageType readFrom(ByteBuf in, boolean decodeInlineCommands) {
61 final int initialIndex = in.readerIndex();
62 final RedisMessageType type = valueOf(in.readByte());
63 if (type == INLINE_COMMAND) {
64 if (!decodeInlineCommands) {
65 throw new RedisCodecException("Decoding of inline commands is disabled");
66 }
67 // reset index to make content readable again
68 in.readerIndex(initialIndex);
69 }
70 return type;
71 }
72
73 /**
74 * Write the message type's prefix to the given buffer.
75 */
76 public void writeTo(ByteBuf out) {
77 if (value == null) {
78 return;
79 }
80 out.writeByte(value.byteValue());
81 }
82
83 private static RedisMessageType valueOf(byte value) {
84 switch (value) {
85 case '+':
86 return SIMPLE_STRING;
87 case '-':
88 return ERROR;
89 case ':':
90 return INTEGER;
91 case '$':
92 return BULK_STRING;
93 case '*':
94 return ARRAY_HEADER;
95 default:
96 return INLINE_COMMAND;
97 }
98 }
99 }