All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.moilioncircle.redis.replicator.cmd.ReplyParser Maven / Gradle / Ivy

Go to download

Redis Replicator implement Redis Replication protocol written in java. It can parse,filter,broadcast the RDB and AOF events in a real time manner. It also can synchronize redis data to your local cache or to database.

There is a newer version: 3.8.1
Show newest version
/*
 * Copyright 2016 leon chen
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.moilioncircle.redis.replicator.cmd;

import com.moilioncircle.redis.replicator.io.RedisInputStream;
import com.moilioncircle.redis.replicator.util.ByteBuilder;

import java.io.IOException;

import static com.moilioncircle.redis.replicator.Constants.*;

/**
 * Created by leon on 8/13/16.
 */
public class ReplyParser {
    private final RedisInputStream in;

    public ReplyParser(RedisInputStream in) {
        this.in = in;
    }

    public Object parse() throws IOException {
        return parse(new BulkReplyHandler.SimpleBulkReplyHandler(), null);
    }

    public Object parse(OffsetHandler offsetHandler) throws IOException {
        return parse(new BulkReplyHandler.SimpleBulkReplyHandler(), offsetHandler);
    }

    public Object parse(BulkReplyHandler handler, OffsetHandler offsetHandler) throws IOException {
        in.mark();
        Object rs = parse(handler);
        long len = in.unmark();
        if (offsetHandler != null) offsetHandler.handle(len);
        return rs;
    }

    /**
     * @param handler bulk string handler
     * @return return Object[] or String or Long
     * @throws IOException when read timeout
     */
    public Object parse(BulkReplyHandler handler) throws IOException {
        int c = in.read();
        switch (c) {
            case DOLLAR:
                //RESP Bulk Strings
                ByteBuilder builder = ByteBuilder.allocate(128);
                while (true) {
                    while ((c = in.read()) != '\r') {
                        builder.put((byte) c);
                    }
                    if ((c = in.read()) == '\n') {
                        break;
                    } else {
                        builder.put((byte) c);
                    }
                }
                long len = Long.parseLong(builder.toString());
                // $-1\r\n. this is called null string.
                // see http://redis.io/topics/protocol
                if (len == -1) return null;
                if (handler != null) return handler.handle(len, in);
                throw new AssertionError("callback is null");
            case COLON:
                // RESP Integers
                builder = ByteBuilder.allocate(128);
                while (true) {
                    while ((c = in.read()) != '\r') {
                        builder.put((byte) c);
                    }
                    if ((c = in.read()) == '\n') {
                        break;
                    } else {
                        builder.put((byte) c);
                    }
                }
                //as integer
                return Long.parseLong(builder.toString());
            case STAR:
                // RESP Arrays
                builder = ByteBuilder.allocate(128);
                while (true) {
                    while ((c = in.read()) != '\r') {
                        builder.put((byte) c);
                    }
                    if ((c = in.read()) == '\n') {
                        break;
                    } else {
                        builder.put((byte) c);
                    }
                }
                len = Long.parseLong(builder.toString());
                if (len == -1) return null;
                Object[] ary = new Object[(int) len];
                for (int i = 0; i < len; i++) {
                    Object obj = parse(new BulkReplyHandler.SimpleBulkReplyHandler());
                    ary[i] = obj;
                }
                return ary;
            case PLUS:
                // RESP Simple Strings
                builder = ByteBuilder.allocate(128);
                while (true) {
                    while ((c = in.read()) != '\r') {
                        builder.put((byte) c);
                    }
                    if ((c = in.read()) == '\n') {
                        return builder.toString();
                    } else {
                        builder.put((byte) c);
                    }
                }
            case MINUS:
                // RESP Errors
                builder = ByteBuilder.allocate(128);
                while (true) {
                    while ((c = in.read()) != '\r') {
                        builder.put((byte) c);
                    }
                    if ((c = in.read()) == '\n') {
                        return builder.toString();
                    } else {
                        builder.put((byte) c);
                    }
                }
            case '\n':
                //skip +CONTINUE\r\n\n
                return parse(new BulkReplyHandler.SimpleBulkReplyHandler());
            default:
                throw new AssertionError("Expect [$,:,*,+,-] but: " + (char) c);

        }
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy