Package com.google.code.hs4j.command.text

Source Code of com.google.code.hs4j.command.text.FindCommand

/**
*Copyright [2010-2011] [dennis zhuang(killme2008@gmail.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
*/
package com.google.code.hs4j.command.text;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.google.code.hs4j.Filter;
import com.google.code.hs4j.FindOperator;
import com.google.code.hs4j.impl.ResultSetImpl;
import com.google.code.hs4j.network.buffer.IoBuffer;
import com.google.code.hs4j.network.hs.HandlerSocketSession;
import com.google.code.hs4j.utils.HSUtils;

/**
* A find command
*
* @author dennis
* @date 2010-11-27
*/
public class FindCommand extends AbstractCommand {
  private static final Filter[] EMPTY_FILTER = new Filter[0];
  private final String id;
  private final String operator;
  private final String[] keys;
  private final int limit;
  private final int offset;
  private final String[] fieldList;
  private Filter[] filters;

  public FindCommand(String id, FindOperator operator, String[] keys,
         int limit, int offset, String[] fieldList){
    this(id, operator, keys, limit, offset, fieldList, null);
  }
  public FindCommand(String id, FindOperator operator, String[] keys,
             int limit, int offset, String[] fieldList, Filter[] filters) {
    super();
    this.id = id;
    this.operator = operator.getValue();
    this.keys = keys;
    this.limit = limit;
    this.offset = offset;
    this.fieldList = fieldList;
    if(filters !=null)
      this.filters = filters;
    else
      this.filters = EMPTY_FILTER;
  }

  @Override
  protected void onDone() {
    if (this.result == null) {
      this.result = new ResultSetImpl(Collections
          .<List<byte[]>> emptyList(), this.fieldList, this.encoding);
    }
  }

  @Override
  protected void decodeBody(HandlerSocketSession session, byte[] data,
      int index) {
    List<List<byte[]>> rows = new ArrayList<List<byte[]>>(this
        .getNumColumns());
    int colOffset = 0;
    int cols = this.fieldList.length;
    List<byte[]> currentRow = new ArrayList<byte[]>(this.fieldList.length);
    int currentCols = 0;
    int colBytesSize = 0;
    for (int i = 0; i < data.length; i++) {
      if (data[i] == TOKEN_SEPARATOR || data[i] == COMMAND_TERMINATE) {
        /**
         * Patched by sam.tingleff
         * "A character in the range [0x00 - 0x0f] is prefixed by 0x01 and shifted by 0x40"
         */
        byte[] colData = new byte[colBytesSize];
        boolean shift = false;
        int colDataIndex = 0;
        // j must be less than i
        for (int j = colOffset; j < i; ++j) {
          byte b = data[j];
          if (b == 0x01)
            shift = true;
          else {
            colData[colDataIndex] = (shift) ? (byte) (b & ~0x40)
                : b;
            shift = false;
            ++colDataIndex;
          }
        }
        currentRow.add(colData);
        colBytesSize = 0; // colBytesSize must reset to zero
        currentCols++;
        colOffset = i + 1;
        if (currentCols == cols) {
          currentCols = 0;
          rows.add(currentRow);
          currentRow = new ArrayList<byte[]>(this.fieldList.length);
        }
      } else if (data[i] != 0x01) {
        ++colBytesSize;
      }

    }
    if (!currentRow.isEmpty()) {
      rows.add(currentRow);
    }
    this.result = new ResultSetImpl(rows, this.fieldList, this.encoding);
  }

  public void encode() {
    String kenLen = String.valueOf(this.keys.length);
    String limitStr = String.valueOf(this.limit);
    String offsetStr = String.valueOf(this.offset);

    byte[][] keyBytes = HSUtils.getByteArrayFromStringArray(keys,this.encoding);
   
    int flen =  filters.length;
    String ftype[] = new String[flen];
    String fop[] = new String[flen];
    String fcol[] = new String[flen];
    byte fval[][] = new byte[flen][];
   
    int filterAllLength=0;
    for(int i=0; i< flen;i++) {
      Filter f = filters[i];
      ftype[i] = f.getType().getValue();
      fop[i] = f.getOperator().getValue();
      fcol[i] = String.valueOf(f.getColumn());
      fval[i] = HSUtils.decodeString(f.getValue(),this.encoding);
      filterAllLength += ftype[i].length()+1 + fop.length+1 + fcol[i].length()+1 + fval[i].length+1;
    }

    int capacity = this.id.length() + 1
        + this.operator.length() + 1 + kenLen.length() + 1
        + this.length(keyBytes) + this.keys.length + limitStr.length()
        + 1 + offsetStr.length() + 1
        + filterAllLength+1;

    IoBuffer buf = IoBuffer.allocate(capacity);
    buf.setAutoExpand(true);
    // id
    this.writeToken(buf, this.id);
    this.writeTokenSeparator(buf);
    // operator
    this.writeToken(buf, this.operator);
    this.writeTokenSeparator(buf);
    // value nums

    this.writeToken(buf, kenLen);
    this.writeTokenSeparator(buf);

    for (byte[] data : keyBytes) {
      this.writeToken(buf, data);
      this.writeTokenSeparator(buf);
    }
    // limit
    this.writeToken(buf, limitStr);
    this.writeTokenSeparator(buf);
    // offset
    this.writeToken(buf, offsetStr);

    // filter
    for(int i=0; i< flen;i++) {
      this.writeTokenSeparator(buf);
      // filter type
      this.writeToken(buf, ftype[i]);
      this.writeTokenSeparator(buf);
      // filter operator
      this.writeToken(buf, fop[i]);
      this.writeTokenSeparator(buf);
      // filter column
      this.writeToken(buf, fcol[i]);
      this.writeTokenSeparator(buf);
      // filter value
      this.writeToken(buf, fval[i]);
    }
    this.writeCommandTerminate(buf);

    buf.flip();
    this.buffer = buf;
  }
}
TOP

Related Classes of com.google.code.hs4j.command.text.FindCommand

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.