content: /*
   * Copyright 1999-2012 Alibaba Group.
   *  
   * 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.
   */
  /**
   * (created at 2011-8-3)
   */
  package com.alibaba.cobar.route.hint;
  
  import java.sql.SQLSyntaxErrorException;
  
  /**
   * Stateless
   * 
   * @author <a href="mailto:shuo.qius@alibaba-inc.com">QIU Shuo</a>
   */
  public abstract class HintParser {
      protected static boolean isDigit(char c) {
          switch (c) {
          case '0':
          case '1':
          case '2':
          case '3':
          case '4':
          case '5':
          case '6':
          case '7':
          case '8':
          case '9':
              return true;
          default:
              return false;
          }
      }
  
      /**
       * hint's {@link CobarHint#getCurrentIndex()} will be changed to index of
       * next char after process
       */
      public abstract void process(CobarHint hint, String hintName, String sql) throws SQLSyntaxErrorException;
  
      private void skipSpace(CobarHint hint, String sql) {
          int ci = hint.getCurrentIndex();
          skip: for (;;) {
              switch (sql.charAt(ci)) {
              case ' ':
              case '\t':
              case '\n':
              case '\r':
                  hint.increaseCurrentIndex();
                  ++ci;
                  break;
              default:
                  break skip;
              }
          }
      }
  
      protected char currentChar(CobarHint hint, String sql) {
          skipSpace(hint, sql);
          return sql.charAt(hint.getCurrentIndex());
      }
  
      /**
       * current char is not separator
       */
      protected char nextChar(CobarHint hint, String sql) {
          skipSpace(hint, sql);
          skipSpace(hint.increaseCurrentIndex(), sql);
          return sql.charAt(hint.getCurrentIndex());
      }
  
      protected Object parsePrimary(CobarHint hint, String sql) throws SQLSyntaxErrorException {
          char c = currentChar(hint, sql);
          int ci = hint.getCurrentIndex();
          switch (c) {
          case '\'':
              StringBuilder sb = new StringBuilder();
              for (++ci;; ++ci) {
                  c = sql.charAt(ci);
                  switch (c) {
                  case '\'':
                      hint.setCurrentIndex(ci + 1);
                      return sb.toString();
                  case '\\':
                      c = sql.charAt(++ci);
                  default:
                      sb.append(c);
                      break;
                  }
              }
          case 'n':
          case 'N':
              hint.setCurrentIndex(ci + "null".length());
              return null;
          default:
              if (isDigit(c)) {
                  int start = ci++;
                  for (; isDigit(sql.charAt(ci)); ++ci) {
                  }
                  hint.setCurrentIndex(ci);
                  return Long.parseLong(sql.substring(start, ci));
              }
              throw new SQLSyntaxErrorException("unknown primary in hint: " + sql);
          }
      }
  
  }
  