Ejemplo n.º 1
0
 public static void writeArray(byte[][] values, ByteBuffer buf) throws IOException {
   if (values.length > Short.MAX_VALUE) {
     throw new IOException("Array exceeds maximum length of " + Short.MAX_VALUE + " bytes");
   }
   buf.putShort((short) values.length);
   for (int i = 0; i < values.length; ++i) {
     if (values[i] == null) {
       buf.putInt(-1); // null length prefix
     } else {
       SerializationHelper.writeArray(values[i], buf);
     }
   }
 }
Ejemplo n.º 2
0
  public void flattenToBuffer(ByteBuffer buf) throws IOException {

    buf.putShort((short) m_params.length);

    for (int i = 0; i < m_params.length; i++) {
      Object obj = m_params[i];
      if ((obj == null) || (obj == JSONObject.NULL)) {
        VoltType type = VoltType.NULL;
        buf.put(type.getValue());
        continue;
      }

      Class<?> cls = obj.getClass();
      if (cls.isArray()) {

        // Since arrays of bytes could be varbinary or strings,
        // and they are the only kind of array needed by the EE,
        // special case them as the VARBINARY type.
        if (obj instanceof byte[]) {
          final byte[] b = (byte[]) obj;
          // commented out this bit... presumably the EE will do this check upon recipt
          /*if (b.length > VoltType.MAX_VALUE_LENGTH) {
              throw new IOException("Value of byte[] larger than allowed max string or varbinary " + VoltType.MAX_VALUE_LENGTH_STR);
          }*/
          buf.put(VoltType.VARBINARY.getValue());
          buf.putInt(b.length);
          buf.put(b);
          continue;
        }

        // Same as before, but deal with the fact it is coming in as a unmanaged bytebuffer
        if (obj instanceof BBContainer) {
          final BBContainer cont = (BBContainer) obj;
          final ByteBuffer paramBuf = cont.b();
          buf.put(VoltType.VARBINARY.getValue());
          buf.putInt(paramBuf.remaining());
          buf.put(paramBuf);
          continue;
        }

        buf.put(ARRAY);

        VoltType type;
        try {
          type = VoltType.typeFromClass(cls.getComponentType());
        } catch (VoltTypeException e) {
          obj = getAKosherArray((Object[]) obj);
          cls = obj.getClass();
          type = VoltType.typeFromClass(cls.getComponentType());
        }

        buf.put(type.getValue());
        switch (type) {
          case SMALLINT:
            SerializationHelper.writeArray((short[]) obj, buf);
            break;
          case INTEGER:
            SerializationHelper.writeArray((int[]) obj, buf);
            break;
          case BIGINT:
            SerializationHelper.writeArray((long[]) obj, buf);
            break;
          case FLOAT:
            SerializationHelper.writeArray((double[]) obj, buf);
            break;
          case STRING:
            if (m_encodedStringArrays[i] == null) {
              // should not happen
              throw new IOException("String array not encoded");
            }
            // This check used to be done by FastSerializer.writeArray(), but things changed?
            if (m_encodedStringArrays[i].length > Short.MAX_VALUE) {
              throw new IOException(
                  "Array exceeds maximum length of " + Short.MAX_VALUE + " bytes");
            }
            buf.putShort((short) m_encodedStringArrays[i].length);
            for (int zz = 0; zz < m_encodedStringArrays[i].length; zz++) {
              SerializationHelper.writeVarbinary(m_encodedStringArrays[i][zz], buf);
            }
            break;
          case TIMESTAMP:
            SerializationHelper.writeArray((TimestampType[]) obj, buf);
            break;
          case DECIMAL:
            // converted long128 in serializer api
            SerializationHelper.writeArray((BigDecimal[]) obj, buf);
            break;
          case VOLTTABLE:
            SerializationHelper.writeArray((VoltTable[]) obj, buf);
            break;
          case VARBINARY:
            SerializationHelper.writeArray((byte[][]) obj, buf);
            break;
          case GEOGRAPHY_POINT:
            SerializationHelper.writeArray((GeographyPointValue[]) obj, buf);
            break;
          case GEOGRAPHY:
            SerializationHelper.writeArray((GeographyValue[]) obj, buf);
            break;
          default:
            throw new RuntimeException("FIXME: Unsupported type " + type);
        }
        continue;
      }

      // Handle NULL mappings not encoded by type.min_value convention
      if (obj == VoltType.NULL_TIMESTAMP) {
        buf.put(VoltType.TIMESTAMP.getValue());
        buf.putLong(VoltType.NULL_BIGINT); // corresponds to EE value.h isNull()
        continue;
      } else if (obj == VoltType.NULL_STRING_OR_VARBINARY) {
        buf.put(VoltType.STRING.getValue());
        buf.putInt(VoltType.NULL_STRING_LENGTH);
        continue;
      } else if (obj == VoltType.NULL_DECIMAL) {
        buf.put(VoltType.DECIMAL.getValue());
        VoltDecimalHelper.serializeNull(buf);
        continue;
      } else if (obj == VoltType.NULL_POINT) {
        buf.put(VoltType.GEOGRAPHY_POINT.getValue());
        GeographyPointValue.serializeNull(buf);
        continue;
      } else if (obj == VoltType.NULL_GEOGRAPHY) {
        buf.put(VoltType.GEOGRAPHY.getValue());
        buf.putInt(VoltType.NULL_STRING_LENGTH);
        continue;
      } else if (obj instanceof BBContainer) {
        final BBContainer cont = (BBContainer) obj;
        final ByteBuffer paramBuf = cont.b();
        buf.put(VoltType.VARBINARY.getValue());
        buf.putInt(paramBuf.remaining());
        buf.put(paramBuf);
        continue;
      }

      VoltType type = VoltType.typeFromClass(cls);
      buf.put(type.getValue());
      switch (type) {
        case TINYINT:
          buf.put((Byte) obj);
          break;
        case SMALLINT:
          buf.putShort((Short) obj);
          break;
        case INTEGER:
          buf.putInt((Integer) obj);
          break;
        case BIGINT:
          buf.putLong((Long) obj);
          break;
        case FLOAT:
          if (cls == Float.class) buf.putDouble(((Float) obj).doubleValue());
          else if (cls == Double.class) buf.putDouble(((Double) obj).doubleValue());
          else throw new RuntimeException("Can't cast parameter type to Double");
          break;
        case STRING:
          if (m_encodedStrings[i] == null) {
            // should not happen
            throw new IOException("String not encoded: " + (String) obj);
          }
          SerializationHelper.writeVarbinary(m_encodedStrings[i], buf);
          break;
        case TIMESTAMP:
          long micros = timestampToMicroseconds(obj);
          buf.putLong(micros);
          break;
        case DECIMAL:
          VoltDecimalHelper.serializeBigDecimal((BigDecimal) obj, buf);
          break;
        case VOLTTABLE:
          ((VoltTable) obj).flattenToBuffer(buf);
          break;
        case GEOGRAPHY_POINT:
          ((GeographyPointValue) obj).flattenToBuffer(buf);
          break;
        case GEOGRAPHY:
          GeographyValue gv = (GeographyValue) obj;
          buf.putInt(gv.getLengthInBytes());
          gv.flattenToBuffer(buf);
          break;
        default:
          throw new RuntimeException("FIXME: Unsupported type " + type);
      }
    }
  }