Exemple #1
0
/*! Sets a sample in the queued output buffer */
void Audio::AudioEngine::setSample( int position, Handle<Value> sample ) {
	int temp;
	switch( m_uSampleFormat ) {
	case paFloat32:
		((float *)m_cachedOutputSampleBlock[m_uCurrentWriteBuffer])[position] = (float)sample->NumberValue();
		break;

	case paInt32:
		((int *)m_cachedOutputSampleBlock[m_uCurrentWriteBuffer])[position] = (int)sample->NumberValue();
		break;

	case paInt24:
		temp = (int)sample->NumberValue();
		m_cachedOutputSampleBlock[m_uCurrentWriteBuffer][3*position + 0] = temp >> 16;
		m_cachedOutputSampleBlock[m_uCurrentWriteBuffer][3*position + 1] = temp >> 8;
		m_cachedOutputSampleBlock[m_uCurrentWriteBuffer][3*position + 2] = temp;
		break;

	case paInt16:
		((int16_t *)m_cachedOutputSampleBlock[m_uCurrentWriteBuffer])[position] = (int16_t)sample->NumberValue();
		break;

	default:
		m_cachedOutputSampleBlock[m_uCurrentWriteBuffer][position] = (char)sample->NumberValue();
		break;
	}
} // end AudioEngine::setSample()
Exemple #2
0
	void SerializeField(google::protobuf::Message *message, const Reflection *r, const FieldDescriptor *field, Handle<Value> val) {
		const EnumValueDescriptor *enumValue = NULL;
		bool repeated = field->is_repeated();

		switch (field->cpp_type()) {
		case FieldDescriptor::CPPTYPE_INT32:
			SET_VALUE(Int32, val->Int32Value());
			break;
		case FieldDescriptor::CPPTYPE_INT64:
			SET_VALUE(Int64, val->NumberValue());
			break;
		case FieldDescriptor::CPPTYPE_UINT32:
			SET_VALUE(UInt32, val->Uint32Value());
			break;
		case FieldDescriptor::CPPTYPE_UINT64:
			SET_VALUE(UInt64, val->NumberValue());
			break;
		case FieldDescriptor::CPPTYPE_DOUBLE:
			SET_VALUE(Double, val->NumberValue());
			break;
		case FieldDescriptor::CPPTYPE_FLOAT:
			SET_VALUE(Float, val->NumberValue());
			break;
		case FieldDescriptor::CPPTYPE_BOOL:
			SET_VALUE(Bool, val->BooleanValue());
			break;
		case FieldDescriptor::CPPTYPE_ENUM:
			enumValue = val->IsNumber() ? 
				field->enum_type()->FindValueByNumber(val->Int32Value()) :
				field->enum_type()->FindValueByName(*String::AsciiValue(val));
			if (enumValue != NULL)
				SET_VALUE(Enum, enumValue);
			break;
		case FieldDescriptor::CPPTYPE_MESSAGE:
			if (val->IsObject()) {
				Type* type = protobuf->GetType(field->message_type());
				type->SerializePart(repeated ?
					r->AddMessage(message, field) :
					r->MutableMessage(message, field), val.As<Object>());
			}
			break;
		case FieldDescriptor::CPPTYPE_STRING:
			if (Buffer::HasInstance(val)) {
				Local<Object> buf = val->ToObject();
				SET_VALUE(String, std::string(Buffer::Data(buf), Buffer::Length(buf)));
			} else {
				String::Utf8Value utf8(val);
				SET_VALUE(String, std::string(*utf8, utf8.length()));
			}
			break;
		}
	}
void printV8Value(Handle<Value> value, bool force=false)
{
    Logging::Level level = force ? Logging::ERROR : Logging::INFO;

    if (!Logging::shouldShow(level)) return;

    HandleScope handleScope;

    if (value.IsEmpty())
        Logging::log(level, "Empty handle\r\n");
    else if (value->IsInt32())
        Logging::log(level, "INT: %d\r\n", value->IntegerValue());
    else if (value->IsNull())
        Logging::log(level, "NULL (null)\r\n");
    else if (value->IsUndefined())
        Logging::log(level, "VOID (undefined)\r\n");
    else if (value->IsBoolean())
        Logging::log(level, "BOOLEAN: %d\r\n", value->BooleanValue());
    else if (value->IsNumber())
        Logging::log(level, "NUMBER: %f\r\n", value->NumberValue());
    else if (value->IsString())
        Logging::log(level, "STRING: ?\r\n");
    else if (value->IsObject())
        Logging::log(level, "OBJECT (object)\r\n");
    else
        Logging::log(level, "Uncertain V8 value\n");
}
/* NAME
 *   Connection::v8Date2OraDate
 *
 * DESCRIPTION
 *   To convert v8::Date value (double value in seconds) to Oracle DB Type
 *
 * PARAMETERS
 *   val      - expected to be a v8::Date Value
 *   bind     - bind structure to update.
 *
 * NOTE:
 *   This function is used for IN Bind parameters, when v8::Date value is
 *   passed, conversion to Oracle-DB Type happens here.
 *
 */
void Connection::v8Date2OraDate ( Handle<Value> val, Bind *bind)
{
  HandleScope scope;
  Handle<Date> date = val.As<Date>();    // Expects to be of v8::Date type

  // Get the number of seconds from 1970-1-1 0:0:0
  *(long double *)(bind->extvalue) = date->NumberValue ();
}
static Handle<Value> uSleepCallback(const Arguments& args){
    if (args.Length() < 1) return v8::Undefined();
    HandleScope scope;
    Handle<Value> arg = args[0];
    double duration = arg->NumberValue();
    usleep((int)duration);
    return v8::Undefined();
}
Exemple #6
0
double GeoJSONReader::valueToDouble(Handle<Value> value) {

    double number = value->NumberValue();
    if (number != number)
        throw "A coordinate value must be numeric";


    return number;
}
Exemple #7
0
 void v8ConvertIn(const Handle<Value> & value, QuantLib::Date & date)
 {
     if (value->IsNumber())
     {
         const double val = value->NumberValue();
         date = QuantLib::Date(val);
     }
     else
     {
         THROW_EXCEPTION("value is not a number");
     }
 }
inline bool setField(OGRFeature* f, int field_index, Handle<Value> val){
	if (val->IsInt32()) {
		f->SetField(field_index, val->Int32Value());
	} else if (val->IsNumber()) {
		f->SetField(field_index, val->NumberValue());
	} else if (val->IsString()) {
		std::string str = *NanUtf8String(val);
		f->SetField(field_index, str.c_str());
	} else if(val->IsNull() || val->IsUndefined()) {
		f->UnsetField(field_index);
	} else {
		return true;
	}
	return false;
}
Exemple #9
0
int Conv::ToJavaDate(JNIEnv *jniEnv, Handle<Value> val, jobject *jVal) {
  double dateTime;
  if(val->IsDate()) {
    dateTime = Date::Cast(*val)->NumberValue();
  } else {
    dateTime = val->NumberValue();
  }
  jobject ob = jniEnv->NewObject(jni.java.util.Date.class_, jni.java.util.Date.ctor, (jlong)dateTime);
  if(ob) {
    *jVal = ob;
    return OK;
  }
  if(jniEnv->ExceptionCheck())
    jniEnv->ExceptionClear();
  return ErrorVM;
}
Exemple #10
0
int Conv::ToJavaString(JNIEnv *jniEnv, Handle<Value> val, jstring *jVal) {
  Handle<String> vString;
  Handle<Value> empty, vRes;
  jstring ob;
  char buf[64];
  switch(GetNaturalType(val)) {
    default: {
      if(val->IsObject()) {
        /* call ToString() in javascript */
        Handle<Object> oVal = val->ToObject();
        Handle<Value> vToString = oVal->Get(sToString);
        if(!vToString.IsEmpty() && vToString->IsFunction()) {
          Handle<Function> fToString = Handle<Function>::Cast(vToString);
          vRes = fToString->CallAsFunction(oVal, 0, &empty);
          if(!vRes.IsEmpty() && (vRes->IsString() || vRes->IsStringObject())) {
            return ToJavaString(jniEnv, vRes->ToString(), jVal);
          }
        }
      }
      return ErrorType;
    }
    case TYPE_UNDEFINED:
    case TYPE_NULL:
      *jVal = 0;
      return OK;
    case TYPE_BOOL:
      return ToJavaString(jniEnv, (val->BooleanValue() ? "true" : "false"), jVal);
    case TYPE_INT:
      sprintf(buf, "%d", val->Int32Value());
      return ToJavaString(jniEnv, buf, jVal);
    case TYPE_LONG:
      sprintf(buf, "%lld", val->IntegerValue());
      return ToJavaString(jniEnv, buf, jVal);
    case TYPE_DOUBLE:
      sprintf(buf, "%g", val->NumberValue());
      return ToJavaString(jniEnv, buf, jVal);
    case TYPE_STRING:
      return ToJavaString(jniEnv, val->ToString(), (jstring *)jVal);
  }
  if(ob) {
    *jVal = ob;
    return OK;
  }
  if(jniEnv->ExceptionCheck())
    jniEnv->ExceptionClear();
  return ErrorVM;
}
void v8_to_gvalue(Handle<Value> v, GValue *gv, GParamSpec *spec) {
	if(v->IsNumber()) {
		g_value_init(gv, G_TYPE_FLOAT);
		g_value_set_float(gv, v->NumberValue());
	} else if(v->IsString()) {
        String::Utf8Value value(v->ToString());
	    if(spec->value_type == GST_TYPE_CAPS) {
	        GstCaps* caps = gst_caps_from_string(*value);
	        g_value_init(gv, GST_TYPE_CAPS);
	        g_value_set_boxed(gv, caps);
	    } else {
	        g_value_init(gv, G_TYPE_STRING);
            g_value_set_string(gv, *value);
	    }
	} else if(v->IsBoolean()) {
		g_value_init(gv, G_TYPE_BOOLEAN);
		g_value_set_boolean(gv, v->BooleanValue());
	}

	return;
}
Exemple #12
0
VALUE rr_v82rb(Handle<Value> value) {
  if (value.IsEmpty()) {
    return rr_v8_value_empty();
  }
  if (value->IsUndefined() || value->IsNull()) {
    return Qnil;
  }
  if (value->IsExternal()) {
    return rr_reflect_v8_external(value);
  }
  if (value->IsUint32()) {
    return UINT2NUM(value->Uint32Value());
  }
  if (value->IsInt32()) {
    return INT2FIX(value->Int32Value());
  }
  if (value->IsBoolean()) {
    return value->BooleanValue() ? Qtrue : Qfalse;
  }
  if (value->IsNumber()) {
    return rb_float_new(value->NumberValue());
  }  
  if (value->IsString()) {
    return rr_reflect_v8_string(value);
  }
  if (value->IsFunction()) {
    return rr_reflect_v8_function(value);
  }
  if (value->IsArray()) {
    return rr_reflect_v8_array(value);
  }
  if (value->IsDate()) {
    return rr_reflect_v8_date(value);
  }
  if (value->IsObject()) {
    return rr_reflect_v8_object(value);
  }
  return rr_wrap_v8_value(value);  
}
/*
   DESCRIPTION
     Processing in binds

   PARAMETERS:
     Handle value, bind struct, eBaton struct
*/
void Connection::GetInBindParams (Handle<Value> v8val, Bind* bind,
                                           eBaton* executeBaton, BindType type)
{
  bind->ind  = 0;
  if(v8val->IsUndefined() || v8val->IsNull())
  {
    bind->value = NULL;
    bind->ind   = -1;
    bind->type        = dpi::DpiVarChar;
  }
  else if(v8val->IsString())
  {
    if( bind->type && bind->type != DATA_STR )
    {
      executeBaton->error= NJSMessages::getErrorMsg(
                             errBindValueAndTypeMismatch, 2);
      goto exitGetInBindParams;
    }

    v8::String::Utf8Value str(v8val->ToString());

    bind->type = dpi::DpiVarChar;
    if(type == BIND_INOUT)
    {
      bind->len = str.length();
    }
    else // IN
    {
      bind->maxSize = bind->len = str.length();
    }
    DPI_SZ_TYPE size = (bind->maxSize >= bind->len ) ?
                        bind->maxSize : bind->len;
    if(size)
    {
      bind->value = (char*)malloc(size);
      if(str.length())
        memcpy(bind->value, *str, str.length());
    }
  }
  else if(v8val->IsInt32())
  {
    if( bind->type && bind->type != DATA_NUM )
    {
      executeBaton->error= NJSMessages::getErrorMsg(
                             errBindValueAndTypeMismatch, 2);
      goto exitGetInBindParams;
    }
    bind->type = dpi::DpiInteger;
    bind->maxSize = bind->len = sizeof(int);
    bind->value = (int*)malloc(bind->len);
    *(int*)(bind->value) = v8val->ToInt32()->Value();
  }
  else if(v8val->IsUint32())
  {
    if( bind->type && bind->type != DATA_NUM )
    {
      executeBaton->error= NJSMessages::getErrorMsg(
                             errBindValueAndTypeMismatch, 2);
      goto exitGetInBindParams;
    }
    bind->type = dpi::DpiUnsignedInteger;
    bind->maxSize = bind->len = sizeof(unsigned int);
    bind->value = (unsigned int*)malloc(bind->len);
    *(unsigned int*)(bind->value) = v8val->ToUint32()->Value();
  }
  else if(v8val->IsNumber())
  {
    if( bind->type && bind->type != DATA_NUM )
    {
      executeBaton->error= NJSMessages::getErrorMsg(errBindValueAndTypeMismatch, 2);
      goto exitGetInBindParams;
    }
    bind->type = dpi::DpiDouble;
    bind->maxSize = bind->len = sizeof(double);
    bind->value = (double*)malloc(bind->len);
    *(double*)(bind->value) = v8val->NumberValue();
  }
  else if(v8val->IsDate ())
  {
    if( bind->type && bind->type != DATA_DATE )
    {
      executeBaton->error= NJSMessages::getErrorMsg(errBindValueAndTypeMismatch, 2);
      goto exitGetInBindParams;
    }
    /* This has to be allocated after stmt is initialized */
    bind->dttmarr = NULL ;
    bind->extvalue = (long double *) malloc (sizeof ( long double ) );
    bind->value = (long double *)malloc (sizeof ( long double ));
    bind->type = dpi::DpiTimestampLTZ;
    bind->len = 0;
    bind->maxSize = 0;
    /* Convert v8::Date value to long double */
    Connection::v8Date2OraDate ( v8val, bind);
  }
  else
  {
    executeBaton->error= NJSMessages::getErrorMsg(errInvalidBindDataType,2);
    goto exitGetInBindParams;
  }
  executeBaton->binds.push_back(bind);
  exitGetInBindParams:
  ;
}
Exemple #14
0
jsvalue JsEngine::AnyFromV8(Handle<Value> value, Handle<Object> thisArg)
{
    jsvalue v;
    
    // Initialize to a generic error.
    v.type = JSVALUE_TYPE_UNKNOWN_ERROR;
    v.length = 0;
    v.value.str = 0;
    
    if (value->IsNull() || value->IsUndefined()) {
        v.type = JSVALUE_TYPE_NULL;
    }                
    else if (value->IsBoolean()) {
        v.type = JSVALUE_TYPE_BOOLEAN;
        v.value.i32 = value->BooleanValue() ? 1 : 0;
    }
    else if (value->IsInt32()) {
        v.type = JSVALUE_TYPE_INTEGER;
        v.value.i32 = value->Int32Value();            
    }
    else if (value->IsUint32()) {
        v.type = JSVALUE_TYPE_INDEX;
        v.value.i64 = value->Uint32Value();            
    }
    else if (value->IsNumber()) {
        v.type = JSVALUE_TYPE_NUMBER;
        v.value.num = value->NumberValue();
    }
    else if (value->IsString()) {
        v = StringFromV8(value);
    }
    else if (value->IsDate()) {
        v.type = JSVALUE_TYPE_DATE;
        v.value.num = value->NumberValue();
    }
    else if (value->IsArray()) {
        Handle<Array> object = Handle<Array>::Cast(value->ToObject());
        v.length = object->Length();
        jsvalue* array = new jsvalue[v.length];
        if (array != NULL) {
            for(int i = 0; i < v.length; i++) {
                array[i] = AnyFromV8(object->Get(i));
            }
            v.type = JSVALUE_TYPE_ARRAY;
            v.value.arr = array;
        }
    }
    else if (value->IsFunction()) {
		Handle<Function> function = Handle<Function>::Cast(value);
		jsvalue* array = new jsvalue[2];
        if (array != NULL) { 
			array[0].value.ptr = new Persistent<Object>(Persistent<Function>::New(function));
			array[0].length = 0;
			array[0].type = JSVALUE_TYPE_WRAPPED;
			if (!thisArg.IsEmpty()) {
				array[1].value.ptr = new Persistent<Object>(Persistent<Object>::New(thisArg));
				array[1].length = 0;
				array[1].type = JSVALUE_TYPE_WRAPPED;
			} else {
				array[1].value.ptr = NULL;
				array[1].length = 0;
				array[1].type = JSVALUE_TYPE_NULL;
			}
	        v.type = JSVALUE_TYPE_FUNCTION;
            v.value.arr = array;
        }
    }
    else if (value->IsObject()) {
        Handle<Object> obj = Handle<Object>::Cast(value);
        if (obj->InternalFieldCount() == 1)
            v = ManagedFromV8(obj);
        else
            v = WrappedFromV8(obj);
    }

    return v;
}
Exemple #15
0
int Conv::ToJavaObject(JNIEnv *jniEnv, Handle<Value> val, int expectedType, jobject *jVal) {

  /* empty, null and undefined convert to null for any nullable type */
  if((expectedType >= TYPE__OB_START) && (val.IsEmpty() || val->IsNull() || val->IsUndefined())) {
    *jVal = 0;
    return OK;
  }

  if(isSequence(expectedType))
    return ToJavaSequence(jniEnv, val, getComponentType(expectedType), (jarray *)jVal);
  
  if(isArray(expectedType))
    return arrayConv->ToJavaArray(jniEnv, val, getComponentType(expectedType), jVal);
  
  if(isMap(expectedType))
    return ToJavaMap(jniEnv, val, getComponentType(expectedType), jVal);
  
  if(isInterface(expectedType))
    return ToJavaInterface(jniEnv, val, getClassId(expectedType), jVal);
  
  if(isDict(expectedType))
    return ToJavaDict(jniEnv, val, getClassId(expectedType), jVal);
  
  HandleScope scope;
  jobject ob;
  switch(expectedType) {
    default:
      return ErrorType;
    case TYPE_BOOL: {
      bool isVoid = val.IsEmpty() ? false : val->BooleanValue();
      ob = jniEnv->CallStaticObjectMethod(jni.anode.js.JSValue_Bool.class_, jni.anode.js.JSValue_Bool.ctor, isVoid);
      break;
    }
    case TYPE_BYTE:
    case TYPE_INT: {
      jint intValue = val.IsEmpty() ? 0 : val->Int32Value();
      ob = jniEnv->CallStaticObjectMethod(jni.anode.js.JSValue_Long.class_, jni.anode.js.JSValue_Long.ctor, (jlong)intValue);
      break;
    }
    case TYPE_LONG: {
      jlong longValue = val.IsEmpty() ? 0 : val->IntegerValue();
      ob = jniEnv->CallStaticObjectMethod(jni.anode.js.JSValue_Long.class_, jni.anode.js.JSValue_Long.ctor, longValue);
      break;
    }
    case TYPE_DOUBLE: {
      jdouble doubleValue = val.IsEmpty() ? 0 : val->NumberValue();
      ob = jniEnv->CallStaticObjectMethod(jni.anode.js.JSValue_Double.class_, jni.anode.js.JSValue_Double.ctor, doubleValue);
      break;
    }
    case TYPE_STRING:
      return ToJavaString(jniEnv, val, (jstring *)jVal);
    case TYPE_DATE:
      return ToJavaDate(jniEnv, val, jVal);
    case TYPE_OBJECT:
      return ToNaturalJavaObject(jniEnv, val, jVal);
    case TYPE_OBJECT|TYPE_BOOL: {
      bool isVoid = val->BooleanValue();
      ob = jniEnv->NewObject(jni.java.lang.Boolean.class_, jni.java.lang.Boolean.ctor, isVoid);
      break;
    }
    case TYPE_OBJECT|TYPE_BYTE: {
      jbyte byteValue = val->Int32Value();
      ob = jniEnv->NewObject(jni.java.lang.Byte.class_, jni.java.lang.Byte.ctor, byteValue);
      break;
    }
    case TYPE_OBJECT|TYPE_INT: {
      jint intValue = val->Int32Value();
      ob = jniEnv->NewObject(jni.java.lang.Integer.class_, jni.java.lang.Integer.ctor, intValue);
      break;
    }
    case TYPE_OBJECT|TYPE_LONG: {
      jlong longValue = val->IntegerValue();
      ob = jniEnv->NewObject(jni.java.lang.Long.class_, jni.java.lang.Long.ctor, longValue);
      break;
    }
    case TYPE_OBJECT|TYPE_DOUBLE: {
      jdouble doubleValue = val->NumberValue();
      ob = jniEnv->NewObject(jni.java.lang.Double.class_, jni.java.lang.Double.ctor, doubleValue);
      break;
    }
  }
  if(ob) {
    *jVal = ob;
    return OK;
  }
  if(jniEnv->ExceptionCheck())
    jniEnv->ExceptionClear();
  return ErrorVM;
}
Exemple #16
0
int Conv::ToNaturalJavaObject(JNIEnv *jniEnv, Handle<Value> val, jobject *jVal) {
  HandleScope scope;
  jobject ob = 0;
  int result = 0;
  switch(GetNaturalType(val)) {
    default:
      return ErrorInvalid;
    case TYPE_UNDEFINED:
    case TYPE_NULL:
      *jVal = 0;
      return OK;
    case TYPE_BOOL:
      ob = jniEnv->NewObject(jni.java.lang.Boolean.class_, jni.java.lang.Boolean.ctor, val->BooleanValue());
      break;
    case TYPE_INT:
      ob = jniEnv->NewObject(jni.java.lang.Integer.class_, jni.java.lang.Integer.ctor, (jint)val->IntegerValue());
      break;
    case TYPE_LONG:
      ob = jniEnv->NewObject(jni.java.lang.Long.class_, jni.java.lang.Long.ctor, val->IntegerValue());
      break;
    case TYPE_DOUBLE:
      ob = jniEnv->NewObject(jni.java.lang.Double.class_, jni.java.lang.Double.ctor, val->NumberValue());
      break;
    case TYPE_STRING:
      return ToJavaString(jniEnv, val->ToString(), (jstring *)jVal);
      break;
    case TYPE_DATE:
      ob = jniEnv->NewObject(jni.java.util.Date.class_, jni.java.util.Date.ctor, val->NumberValue());
      break;
    case TYPE_FUNCTION: {
      Handle<Function> fVal = Handle<Function>::Cast(val->ToObject());
      result = UnwrapObject(jniEnv, fVal, sObjectHiddenKey, jVal);
      if(result == ErrorNotfound)
        result = WrapV8Object(jniEnv, fVal, jVal);
      break;
    }
    case TYPE_ARRAY: {
      Handle<Array> aVal = Handle<Array>::Cast(val->ToObject());
      result = UnwrapObject(jniEnv, aVal, arrayConv->getHiddenKey(), jVal);
      if(result == ErrorNotfound)
        result = arrayConv->WrapV8Array(jniEnv, aVal, jVal);
      break;
    }
    case TYPE_OBJECT: {
      Handle<Object> oVal = Handle<Object>::Cast(val->ToObject());
      result = UnwrapObject(jniEnv, oVal, sObjectHiddenKey, jVal);
      if(result == ErrorNotfound)
        result = WrapV8Object(jniEnv, oVal, jVal);
      break;
    }
  }
  if(jniEnv->ExceptionCheck()) {
    jniEnv->ExceptionClear();
    return ErrorVM;
  }
  if(ob) {
    *jVal = ob;
    return OK;
  }
  return result;
}
    bool QueryOperation::BindParameters( Handle<Array> node_params )
    {
        uint32_t count = node_params->Length();

        if( count > 0 ) {

            for( uint32_t i = 0; i < count; ++i ) {

                Local<Value> p = node_params->Get( i );
                ParamBinding binding;

                if( p->IsNull() ) {

                    binding.js_type = ParamBinding::JS_NULL;
                    binding.c_type = SQL_C_CHAR;
                    binding.sql_type = SQL_CHAR;
                    binding.param_size = 1;
                    binding.digits = 0;
                    binding.buffer = NULL;
                    binding.buffer_len = 0;
                    binding.indptr = SQL_NULL_DATA;
                }
                else if( p->IsString() ) {

                    binding.js_type = ParamBinding::JS_STRING;
                    binding.c_type = SQL_C_WCHAR;
                    binding.sql_type = SQL_WVARCHAR;
                    Local<String> str_param = p->ToString();
                    int str_len = str_param->Length();
                    binding.buffer = new uint16_t[ str_len + 1 ];   // null terminator
                    str_param->Write( static_cast<uint16_t*>( binding.buffer ));
                    if( str_len > 4000 ) {
                        binding.param_size = 0;     // max types require 0 precision
                    }
                    else {
                        binding.param_size = str_len;
                    }
                    binding.buffer_len = str_len * sizeof( uint16_t );
                    binding.digits = 0;
                    binding.indptr = binding.buffer_len;
                }
                else if( p->IsBoolean() ) {
                    
                    binding.js_type = ParamBinding::JS_BOOLEAN;
                    binding.c_type = SQL_C_BIT;
                    binding.sql_type = SQL_BIT;
                    binding.buffer = new uint16_t;
                    binding.buffer_len = sizeof( uint16_t );
                    *static_cast<uint16_t*>( binding.buffer ) = p->BooleanValue();
                    binding.param_size = 1;
                    binding.digits = 0;
                    binding.indptr = binding.buffer_len;
                }
                else if( p->IsInt32()) {

                    binding.js_type = ParamBinding::JS_INT;
                    binding.c_type = SQL_C_SLONG;
                    binding.sql_type = SQL_INTEGER;
                    binding.buffer = new int32_t;
                    binding.buffer_len = sizeof( int32_t );
                    *static_cast<int32_t*>( binding.buffer ) = p->Int32Value();
                    binding.param_size = sizeof( int32_t );
                    binding.digits = 0;
                    binding.indptr = binding.buffer_len;
                }
                else if( p->IsUint32()) {

                    binding.js_type = ParamBinding::JS_UINT;
                    binding.c_type = SQL_C_ULONG;
                    binding.sql_type = SQL_BIGINT;
                    binding.buffer = new uint32_t;
                    binding.buffer_len = sizeof( uint32_t );
                    *static_cast<int32_t*>( binding.buffer ) = p->Uint32Value();
                    binding.param_size = sizeof( uint32_t );
                    binding.digits = 0;
                    binding.indptr = binding.buffer_len;
                }
                else if( p->IsNumber()) {

                    // numbers can be either integers or doubles.  We attempt to determine which it is through a simple
                    // cast and equality check
                    double d = p->NumberValue();
                    if( _isnan( d ) || !_finite( d ) ) {

                        return ParameterErrorToUserCallback( i, "Invalid number parameter" );

                    }
                    else if( d == floor( d ) && 
                             d >= std::numeric_limits<int64_t>::min() && 
                             d <= std::numeric_limits<int64_t>::max() ) {

                        binding.js_type = ParamBinding::JS_NUMBER;
                        binding.c_type = SQL_C_SBIGINT;
                        binding.sql_type = SQL_BIGINT;
                        binding.buffer = new int64_t;
                        binding.buffer_len = sizeof( int64_t );
                        *static_cast<int64_t*>( binding.buffer ) = p->IntegerValue();
                        binding.param_size = sizeof( int64_t );
                        binding.digits = 0;
                        binding.indptr = binding.buffer_len;
                    }
                    else {

                        binding.js_type = ParamBinding::JS_NUMBER;
                        binding.c_type = SQL_C_DOUBLE;
                        binding.sql_type = SQL_DOUBLE;
                        binding.buffer = new double;
                        binding.buffer_len = sizeof( double );
                        *static_cast<double*>( binding.buffer ) = p->NumberValue();
                        binding.param_size = sizeof( double );
                        binding.digits = 0;
                        binding.indptr = binding.buffer_len;
                    }
                }
                else if( p->IsDate() ) {

                    // Since JS dates have no timezone context, all dates are assumed to be UTC
                    Handle<Date> dateObject = Handle<Date>::Cast<Value>( p );
                    assert( !dateObject.IsEmpty() );
                    // dates in JS are stored internally as ms count from Jan 1, 1970
                    double d = dateObject->NumberValue();
                    SQL_SS_TIMESTAMPOFFSET_STRUCT* sql_tm = new SQL_SS_TIMESTAMPOFFSET_STRUCT;
                    TimestampColumn sql_date( d );
                    sql_date.ToTimestampOffset( *sql_tm );

                    binding.js_type = ParamBinding::JS_DATE;
                    binding.c_type = SQL_C_BINARY;
                    // TODO: Determine proper SQL type based on version of server we're talking to
                    binding.sql_type = SQL_SS_TIMESTAMPOFFSET;
                    binding.buffer = sql_tm;
                    binding.buffer_len = sizeof( SQL_SS_TIMESTAMPOFFSET_STRUCT );
                    // TODO: Determine proper precision and size based on version of server we're talking to
                    binding.param_size = SQL_SERVER_2008_DEFAULT_DATETIME_PRECISION;
                    binding.digits = SQL_SERVER_2008_DEFAULT_DATETIME_SCALE;
                    binding.indptr = binding.buffer_len;
                }
                else if( p->IsObject() && node::Buffer::HasInstance( p )) {

                    // TODO: Determine if we need something to keep the Buffer object from going
                    // away while we use it we could just copy the data, but with buffers being 
                    // potentially very large, that could be problematic
                    Local<Object> o = p.As<Object>();
                    
                    binding.js_type = ParamBinding::JS_BUFFER;
                    binding.c_type = SQL_C_BINARY;
                    binding.sql_type = SQL_VARBINARY;
                    binding.buffer = node::Buffer::Data( o );
                    binding.buffer_len = node::Buffer::Length( o );
                    binding.param_size = binding.buffer_len;
                    binding.digits = 0;
                    binding.indptr = binding.buffer_len;
                }

                else {


                    return ParameterErrorToUserCallback( i, "Invalid parameter type" );

                }

                params.push_back( move( binding ));
            }
        }

        return true;
    }
void SerializeField(google::protobuf::Message *message, const Reflection *r, const FieldDescriptor *field, Handle<Value> val) {
	const EnumValueDescriptor *enumValue = NULL;
	bool repeated = field->is_repeated();

	if (*val != NULL) {
		if (field->is_optional() && (val->IsNull() || val->IsUndefined()))
			return;
		
		switch (field->cpp_type()) {
			case FieldDescriptor::CPPTYPE_INT32: {
				if (repeated)
					r->AddInt32(message, field, val->Int32Value());
				else
					r->SetInt32(message, field, val->Int32Value());
				break;
			}
			case FieldDescriptor::CPPTYPE_INT64:
				if (repeated)
					if (preserve_int64 && val->IsArray()) {
						Local<Object> n64_array = val->ToObject();
						uint64 n64;
						uint32 hi = n64_array->Get(0)->Uint32Value(), lo = n64_array->Get(1)->Uint32Value();
						n64 = ((uint64)hi << 32) + (uint64)lo;
						r->AddInt64(message, field, n64);
					} else
						r->AddInt64(message, field, val->NumberValue());
				else
					if (preserve_int64 && val->IsArray()) {
						Local<Object> n64_array = val->ToObject();
						uint64 n64;
						uint32 hi = n64_array->Get(0)->Uint32Value(), lo = n64_array->Get(1)->Uint32Value();
						n64 = ((uint64)hi << 32) + (uint64)lo;
						r->SetInt64(message, field, n64);
					} else
						r->SetInt64(message, field, val->NumberValue());
				break;
			case FieldDescriptor::CPPTYPE_UINT32:
				if (repeated)
					r->AddUInt32(message, field, val->Uint32Value());
				else
					r->SetUInt32(message, field, val->Uint32Value());
				break;
			case FieldDescriptor::CPPTYPE_UINT64:
				if (repeated)
					if (preserve_int64 && val->IsArray()) {
						Local<Object> n64_array = val->ToObject();
						uint64 n64;
						uint32 hi = n64_array->Get(0)->Uint32Value(), lo = n64_array->Get(1)->Uint32Value();
						n64 = ((uint64)hi << 32) + (uint64)lo;
						r->AddUInt64(message, field, n64);
					} else
						r->AddUInt64(message, field, val->NumberValue());
				else
					if (preserve_int64 && val->IsArray()) {
						Local<Object> n64_array = val->ToObject();
						uint64 n64;
						uint32 hi = n64_array->Get(0)->Uint32Value(), lo = n64_array->Get(1)->Uint32Value();
						n64 = ((uint64)hi << 32) + (uint64)lo;
						r->SetUInt64(message, field, n64);
					} else
						r->SetUInt64(message, field, val->NumberValue());
				break;
			case FieldDescriptor::CPPTYPE_DOUBLE:
				if (repeated)
					r->AddDouble(message, field, val->NumberValue());
				else
					r->SetDouble(message, field, val->NumberValue());
				break;
			case FieldDescriptor::CPPTYPE_FLOAT:
				if (repeated)
					r->AddFloat(message, field, val->NumberValue());
				else
					r->SetFloat(message, field, val->NumberValue());
				break;
			case FieldDescriptor::CPPTYPE_BOOL:
				if (repeated)
					r->AddBool(message, field, val->BooleanValue());
				else
					r->SetBool(message, field, val->BooleanValue());
				break;
			case FieldDescriptor::CPPTYPE_ENUM:
				// TODO: possible memory leak?
				enumValue =
					val->IsNumber() ?
						field->enum_type()->FindValueByNumber(val->Int32Value()) :
						field->enum_type()->FindValueByName(*NanAsciiString(val));

				if (enumValue != NULL) {
					if (repeated)
						r->AddEnum(message, field, enumValue);
					else
						r->SetEnum(message, field, enumValue);
				}
				break;
			case FieldDescriptor::CPPTYPE_MESSAGE:
				if (val->IsObject()) {
					if (repeated)
						SerializePart(r->AddMessage(message, field), val.As<Object>());
					else
						SerializePart(r->MutableMessage(message, field), val.As<Object>());
				}
				break;
			case FieldDescriptor::CPPTYPE_STRING:
				if (Buffer::HasInstance(val)) {
					Local<Object> buf = val->ToObject();
					if (repeated)
						r->AddString(message, field, std::string(Buffer::Data(buf), Buffer::Length(buf)));
					else
						r->SetString(message, field, std::string(Buffer::Data(buf), Buffer::Length(buf)));
					break;
				}

				if (val->IsObject()) {
					Local<Object> val2 = val->ToObject();
					Local<Value> converter = val2->Get(NanNew<String>("toProtobuf"));
					if (converter->IsFunction()) {
						Local<Function> toProtobuf = Local<Function>::Cast(converter);
						Local<Value> ret = toProtobuf->Call(val2,0,NULL);
						if (Buffer::HasInstance(ret)) {
							Local<Object> buf = ret->ToObject();
							if (repeated)
								r->AddString(message, field, std::string(Buffer::Data(buf), Buffer::Length(buf)));
							else
								r->SetString(message, field, std::string(Buffer::Data(buf), Buffer::Length(buf)));
							break;
						}
					}
				}
				String::Utf8Value temp(val->ToString());
				std::string value = std::string(*temp);
				if (repeated)
					r->AddString(message, field, value);
				else
					r->SetString(message, field, value);
				break;
		}
	}
}