示例#1
0
  void TypedArray (const Wrapper* wrapper, Handle<Value> value, vector<void*>& natives) {
    void *buff = NULL;
    size_t byteLength = 0;

    if (value->IsObject()) {
      Handle<Object> obj = value->ToObject();
      if (obj->HasIndexedPropertiesInExternalArrayData()) {
        buff = obj->GetIndexedPropertiesExternalArrayData();
        byteLength = obj->GetIndexedPropertiesExternalArrayDataLength();

        switch (obj->GetIndexedPropertiesExternalArrayDataType()) {
        case kExternalByteArray:
        case kExternalUnsignedByteArray:
        case kExternalPixelArray:
          break;
        case kExternalShortArray:
        case kExternalUnsignedShortArray:
          byteLength *= 2;
          break;
        case kExternalIntArray:
        case kExternalUnsignedIntArray:
        case kExternalFloatArray:
          byteLength *= 4;
          break;
        case kExternalDoubleArray:
          byteLength *= 8;
          break;
        }
      } else {
        buff = Get<void*>(value);
      }
    }

    PushBackWrapped(natives, buff);
    PushBackWrapped(natives, byteLength);
  }
示例#2
0
    Handle<Value> CreateExternalArray(const Arguments& args,
                                             ExternalArrayType type,
                                             size_t element_size) {
		TryCatch try_catch;
		ASSERT_PIN(element_size == 1 || element_size == 2 ||
			 element_size == 4 || element_size == 8, "CreateExternalArray");

		// Currently, only the following constructors are supported:
		//   TypedArray(unsigned long length)
		//   TypedArray(ArrayBuffer buffer,
		//              optional unsigned long byteOffset,
		//              optional unsigned long length)
		Handle<Object> buffer;
		int32_t length;
		int32_t byteLength;
		int32_t byteOffset;
		int32_t bufferLength;

		if (args.Length() == 0) {
		return ThrowException(
			String::New("Array constructor must have at least one parameter."));
		}

		if (args[0]->IsObject() &&
			(!args[0]->ToObject()->GetHiddenValue(String::New(kArrayBufferMarkerPropName)).IsEmpty()) ||
			(IS_BINARY(args[0]))) {
				if (!args[0]->ToObject()->GetHiddenValue(String::New(kArrayBufferMarkerPropName)).IsEmpty()) {
					buffer = args[0]->ToObject();
					bufferLength = convertToUint(buffer->Get(String::New("byteLength")), &try_catch);
					if (try_catch.HasCaught())
						return try_catch.Exception();
				} else {
					buffer = CreateExternalArrayBuffer(args[0])->ToObject();
					bufferLength = convertToUint(buffer->Get(String::New("byteLength")), &try_catch);
					if (try_catch.HasCaught())
						return try_catch.Exception();
				}

		if (args.Length() < 2 || args[1]->IsUndefined()) {
		  byteOffset = 0;
		} else {
		  byteOffset = convertToUint(args[1], &try_catch);
		  if (try_catch.HasCaught()) return try_catch.Exception();
		  if (byteOffset > bufferLength) {
			return ThrowException(String::New("byteOffset out of bounds"));
		  }
		  if (byteOffset % element_size != 0) {
			return ThrowException(
				String::New("byteOffset must be multiple of element_size"));
		  }
		}

		if (args.Length() < 3 || args[2]->IsUndefined()) {
		  byteLength = bufferLength - byteOffset;
		  length = byteLength / element_size;
		  if (byteLength % element_size != 0) {
			return ThrowException(
				String::New("buffer size must be multiple of element_size"));
		  }
		} else {
			  length = convertToUint(args[2], &try_catch);
			  if (try_catch.HasCaught())
				  return try_catch.Exception();
			  byteLength = length * element_size;
			  if (byteOffset + byteLength > bufferLength) {
				  return ThrowException(String::New("length out of bounds"));
			  }
		}
		} else {
			length = convertToUint(args[0], &try_catch);
			byteLength = length * element_size;
			byteOffset = 0;
			Handle<Value> result = CreateExternalArrayBuffer(byteLength);
			if (!result->IsObject())
				return result;
			buffer = result->ToObject();
		}

		void* data = buffer->GetIndexedPropertiesExternalArrayData();
		ASSERT_PIN(data != NULL, "CreateExternalArray data != NULL");

		Handle<Object> array = Object::New();
		array->SetIndexedPropertiesToExternalArrayData(
		  static_cast<uint8_t*>(data) + byteOffset, type, length);
		array->Set(String::New("byteLength"), Int32::New(byteLength), ReadOnly);
		array->Set(String::New("byteOffset"), Int32::New(byteOffset), ReadOnly);
		array->Set(String::New("length"), Int32::New(length), ReadOnly);
		array->Set(String::New("BYTES_PER_ELEMENT"), Int32::New(element_size));
		array->Set(String::New("buffer"), buffer, ReadOnly);

		return array;
    }