Package com.cetsoft.imcache.cache.redis.client

Source Code of com.cetsoft.imcache.cache.redis.client.Protocol

/*
* Copyright (C) 2014 Cetsoft, http://www.cetsoft.com
*
* 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.
*
* Author : Yusuf Aytas
* Date   : Sep 8, 2014
*/
package com.cetsoft.imcache.cache.redis.client;

import com.cetsoft.imcache.cache.redis.client.exception.RedisConnectionException;
import com.cetsoft.imcache.cache.redis.client.util.RedisInputStream;
import com.cetsoft.imcache.cache.redis.client.util.RedisOutputStream;
import com.cetsoft.imcache.cache.redis.client.util.SafeEncoder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
* The Class Protocol.
*/
public final class Protocol {

  /** The Constant DEFAULT_PORT. */
  public static final int DEFAULT_PORT = 6379;

  /** The Constant DEFAULT_SENTINEL_PORT. */
  public static final int DEFAULT_SENTINEL_PORT = 26379;

  /** The Constant DEFAULT_TIMEOUT. */
  public static final int DEFAULT_TIMEOUT = 2000;

  /** The Constant DEFAULT_DATABASE. */
  public static final int DEFAULT_DATABASE = 0;

  /** The Constant CHARSET. */
  public static final String CHARSET = "UTF-8";

    private static final String ASK_RESPONSE = "ASK";
    private static final String MOVED_RESPONSE = "MOVED";
    private static final String CLUSTERDOWN_RESPONSE = "CLUSTERDOWN";

    public static final byte DOLLAR_BYTE = '$';
    public static final byte ASTERISK_BYTE = '*';
    public static final byte PLUS_BYTE = '+';
    public static final byte MINUS_BYTE = '-';
    public static final byte COLON_BYTE = ':';

  /**
   * The Enum Command.
   */
  public static enum Command {

    /** The ping. */
    PING,
    /** The set. */
    SET,
    /** The get. */
    GET,
    /** The quit. */
    QUIT,
    /** The exists. */
    EXISTS,
    /** The del. */
    DEL,
    /** The type. */
    TYPE,
    /** The flushdb. */
    FLUSHDB,
    /** The keys. */
    KEYS,
    /** The expire. */
    EXPIRE,
    /** The expireat. */
    EXPIREAT,
    /** The ttl. */
    TTL;

    /** The raw bytes. */
    public final byte[] raw;

    /**
     * Instantiates a new command.
     */
    Command() {
      raw = SafeEncoder.encode(this.name());
    }
  }

    public static void sendCommand(final RedisOutputStream os, final Command command, final byte[]... args) {
        sendCommand(os, command.raw, args);
    }

    public static void sendCommand(final RedisOutputStream os, final byte[] command, final byte[]... args) {
        try {
            os.write(ASTERISK_BYTE);
            os.writeIntCrLf(args.length);
            os.write(DOLLAR_BYTE);
            os.writeIntCrLf(command.length);
            os.write(command);
            os.writeCrLf();

            for (final byte[] arg : args) {
                os.write(DOLLAR_BYTE);
                os.writeIntCrLf(arg.length);
                os.write(arg);
                os.writeCrLf();
            }
        } catch (IOException e) {
            throw new RedisConnectionException(e);
        }
    }

    public static Object read(final RedisInputStream is) {
        return process(is);
    }

    private static Object process(final RedisInputStream is) {
        try {
            int b = is.readByte();
            if (b == MINUS_BYTE) {
                processError(is);
            } else if (b == ASTERISK_BYTE) {
                int num = Integer.parseInt(is.readLine());
                if (num == -1) {
                    return null;
                }
                List<Object> ret = new ArrayList<Object>(num);
                for (int i = 0; i < num; i++) {
                    //TODO:UPDATE THIS
                    ret.add(process(is));
                }
            } else if (b == COLON_BYTE) {
                return processInteger(is);
            } else if (b == DOLLAR_BYTE) {
                return processBulkReply(is);
            } else if (b == PLUS_BYTE) {
                return processStatusCodeReply(is);
            } else {
                throw new RedisConnectionException("unknown reply: " + (char) b);
            }
        } catch (IOException e) {
            throw new RedisConnectionException(e);
        }

        return null;
    }

    private static void processError(final RedisInputStream is) {
        String message = is.readLine();
        if (message.startsWith(MOVED_RESPONSE)) {
        } else if (message.startsWith(ASK_RESPONSE)) {
        } else if (message.startsWith(CLUSTERDOWN_RESPONSE)) {
        }
    }

    private static Long processInteger(final RedisInputStream is) {
        String num = is.readLine();
        return Long.valueOf(num);
    }

    private static byte[] processBulkReply(final RedisInputStream is) {
        int len = Integer.valueOf(is.readLine());
        if (len == -1) {
            return null;
        }
        byte[] read = new byte[len];
        int offset = 0;
        try {
            while (offset < len) {
                int size = is.read(read, offset, (len - offset));
                if (size == -1) {
                    throw new RedisConnectionException("it seems that server has closed the connection");
                }

                offset += size;
            }

            // read 2 more bytes
            is.readByte();
            is.readByte();
        } catch (IOException e) {
            throw new RedisConnectionException(e);
        }

        return read;
    }

    private static byte[] processStatusCodeReply(final RedisInputStream is) {
        return SafeEncoder.encode(is.readLine());
    }
}
TOP

Related Classes of com.cetsoft.imcache.cache.redis.client.Protocol

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.