Пример #1
0
	Handle<Value> CreateExternalArrayBuffer(const Arguments& args) {
	  if (args.Length() == 0) {
		return ThrowException(
			String::New("ArrayBuffer constructor must have one parameter."));
	  }

	  if (args[0]->IsObject() && IS_BINARY(args[0])) {
		  return CreateExternalArrayBuffer(args[0]);
	  }

	  TryCatch try_catch;
	  int32_t length = convertToUint(args[0], &try_catch);
	  if (try_catch.HasCaught()) return try_catch.Exception();

	  return CreateExternalArrayBuffer(length);
	}
// This command is complex because it only allows setting of frequency for channel 1
// This is because only the tilt motor can be controlled by frequency
void onCommandFrequencyOutput()
{
	if (isChannelCorrect(gParameters[0]))
	{
		uint8_t channel = convertToInt(gParameters[0]);
		uint16_t frequency = convertToUint(gParameters[1]);

		if (channel == TILT_CHANNEL)
		{
			if (isReadCommand(gParameters[1]))
			{
				sendInt(currentFrequency);
				sendAck();
			}
			else
			{
				if (!isSafetyOn)
				{
					if (isIntWithinRange(frequency, MOTOR_MIN_FREQUENCY, MOTOR_MAX_FREQUENCY))
					{
						setFrequency(frequency);
						sendAck();
					}
					else
					{
						sendIntRangeError(MOTOR_MIN_FREQUENCY, MOTOR_MAX_FREQUENCY, HERTZ_UNIT);
					}
				}
				else
				{
					Serial.println(F("Cannot change frequency output while safety is on."));
					sendNack();
				}
			}
		}
		else
		{
			Serial.println(F("Changing or reading of frequency only applies to channel 1"));
			sendNack();
		}
	}
	else
	{
		sendChannelError();
	}
}
Пример #3
0
	//by default memory buffers have direct access
    Handle<Value> MemoryBuffer(const Arguments& args) {
	  HandleScope scope;

	  if (args.Length() < 2) {
		return ThrowException(
			String::New("MemoryBuffer constructor must have two parameters (address and size)."));
	  }

	  TryCatch try_catch;
	  uint32_t address = NumberToUint32(args[0], &try_catch);
	  uint32_t length = convertToUint(args[1], &try_catch);
	  uint8_t* data;
	  bool is_external = false;

	  if (try_catch.HasCaught()) return try_catch.Exception();

	  static const int32_t kMaxSize = 0x7fffffff;
	  // Make sure the total size fits into a (signed) int.
	  if (length < 0 || length > kMaxSize) {
		return ThrowException(String::New("ArrayBuffer exceeds maximum size (2G)"));
	  }

	  //check if we should snapshot the value
	  if (args.Length() > 2 && args[2]->IsTrue()) {
		  data = new uint8_t[length];
		  if (data == NULL) {
			return ThrowException(String::New("Memory allocation failed."));
		  }
		  V8::AdjustAmountOfExternalAllocatedMemory(length);

		  PIN_SafeCopy(data, reinterpret_cast<uint8_t *>(address), length);
	  } else {
		  data = reinterpret_cast<uint8_t *>(address);
		  is_external = true;
	  }

	  Handle<Value> buffer = CreateExternalArrayBuffer(length, data);
	  buffer->ToObject()->Set(String::New("snapshot"), (is_external ? False() : True()), ReadOnly);

	  if (is_external)
		buffer->ToObject()->Set(String::New("externalBuffer"), True(), ReadOnly);

	  return scope.Close(buffer);
    }
Пример #4
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;
    }