Esempio n. 1
0
/*
 * Unmarshal an array argument.
 *
 * @param msg   The message
 * @param sig   The array element signature
 * @param arg   Pointer to the structure to return the array
 */
static AJ_Status UnmarshalArray(AJ_Message* msg, const char** sig, AJ_Arg* arg, uint8_t pad)
{
    AJ_Status status;
    AJ_IOBuffer* ioBuf = &msg->bus->sock.rx;
    char typeId = **sig;
    uint32_t numBytes;

    /*
     * Get the byte count for the array
     */
    status = LoadBytes(ioBuf, 4, pad);
    if (status != AJ_OK) {
        return status;
    }
    EndianSwap(msg, AJ_ARG_UINT32, ioBuf->readPtr, 1);
    numBytes = *((uint32_t*)ioBuf->readPtr);
    ioBuf->readPtr += 4;
    /*
     * We are already aligned on 4 byte boundary but there may be padding after the array length if
     * the array element types align on an 8 byte boundary.
     */
    pad = PadForType(typeId, ioBuf);
    status = LoadBytes(ioBuf, numBytes, pad);
    if (status != AJ_OK) {
        return status;
    }
    arg->val.v_data = ioBuf->readPtr;
    arg->sigPtr = *sig;
    arg->len = numBytes;
    if (IsScalarType(typeId)) {
        /*
         * For scalar types we do an inplace endian swap (if needed) and return a pointer into the read buffer.
         */
        EndianSwap(msg, typeId, (void*)arg->val.v_data, arg->len);
        ioBuf->readPtr += numBytes;
        arg->typeId = typeId;
        arg->flags = AJ_ARRAY_FLAG;
    } else {
        /*
         * For all other types the elements must be individually unmarshalled.
         */
        arg->typeId = AJ_ARG_ARRAY;
    }
    /*
     * Consume the array element signature.
     */
    *sig += CompleteTypeSigLen(*sig);
    return status;
}
Esempio n. 2
0
AJ_Status AJ_CloseMsg(AJ_Message* msg)
{
    AJ_Status status = AJ_OK;
    /*
     * This function is idempotent
     */
    if (msg->bus) {
        AJ_IOBuffer* ioBuf = &msg->bus->sock.rx;
        /*
         * Skip any unconsumed bytes
         */
        while (msg->bodyBytes) {
            uint16_t sz = AJ_IO_BUF_AVAIL(ioBuf);
            sz = min(sz, msg->bodyBytes);
            if (!sz) {
                AJ_IO_BUF_RESET(ioBuf);
                sz = min(msg->bodyBytes, ioBuf->bufSize);
            }
            status = LoadBytes(ioBuf, sz, 0);
            if (status != AJ_OK) {
                break;
            }
            msg->bodyBytes -= sz;
            ioBuf->readPtr += sz;
        }
        memset(msg, 0, sizeof(AJ_Message));
#ifndef NDEBUG
        currentMsg = NULL;
#endif
    }
    return status;
}
Esempio n. 3
0
bool ff::LoadBytes(IDataReader *pReader, void *pMem, size_t nBytes)
{
	const BYTE* pData = LoadBytes(pReader, nBytes);
	assertRetVal(pData && pMem, false);

	CopyMemory(pMem, pData, nBytes);

	return true;
}
Esempio n. 4
0
/**
 * @brief Cargador del buffer
 *
 * @param entrada Buffer de entrada para cargar en #buffer
 *
 * Se cargan los primeros #buffer_size bytes del buffer de entrada (entrada) en la variable #buffer.
 * Posteriormente, se cambia el estado del mensaje a lecutra (READING).
 */
void CNetMessageN::LoadNBytes(char* entrada)
{
  charbuf c;

  for(uint i = 0; i < buffer_size; i++)
    c[i] = entrada[i];

  LoadBytes(c, buffer_size);
  finish();
}
Esempio n. 5
0
bool ff::LoadData<ff::String>(IDataReader *pReader, StringOut data)
{
	DWORD nBytes = 0;
	assertRetVal(LoadData(pReader, nBytes), false);

	const BYTE* sz = LoadBytes(pReader, (size_t)nBytes);
	assertRetVal(sz, false);
	data.assign((const wchar_t *)sz, (nBytes / sizeof(wchar_t)) - 1);

	return true;
}
Esempio n. 6
0
/*
 * Unmarshal a struct or dict entry argument.
 *
 * @param msg      The message
 * @param sig      The struct signature
 * @param arg      Pointer to the arg structure to return
 */
static AJ_Status UnmarshalStruct(AJ_Message* msg, const char** sig, AJ_Arg* arg, uint8_t pad)
{
    AJ_IOBuffer* ioBuf = &msg->bus->sock.rx;
    AJ_Status status = LoadBytes(ioBuf, 0, pad);
    arg->val.v_data = ioBuf->readPtr;
    arg->sigPtr = *sig;
    /*
     * Consume the entire struct signature.
     */
    *sig -= 1;
    *sig += CompleteTypeSigLen(*sig);
    return status;
}
Esempio n. 7
0
static bool InternalLoadValue(ff::IDataReader *reader, ff::Value **value)
{
	assertRetVal(reader && value, false);

	DWORD type = 0;
	assertRetVal(ff::LoadData(reader, type), false);

	ff::Value::Type valueType = (ff::Value::Type)type;
	switch (valueType)
	{
	default:
		assertRetVal(false, false);

	case ff::Value::Type::Null:
		assertRetVal(ff::Value::CreateNull(value), false);
		break;

	case ff::Value::Type::Bool:
		{
			bool val = false;
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreateBool(val, value), false);
		}
		break;

	case ff::Value::Type::Double:
		{
			double val = 0;
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreateDouble(val, value), false);
		}
		break;

	case ff::Value::Type::Float:
		{
			float val = 0;
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreateFloat(val, value), false);
		}
		break;

	case ff::Value::Type::Int:
		{
			int val = 0;
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreateInt(val, value), false);
		}
		break;

	case ff::Value::Type::Data:
		{
			DWORD valueSize = 0;
			assertRetVal(ff::LoadData(reader, valueSize), false);

			ff::ComPtr<ff::IData> valueData;
			assertRetVal(ff::LoadBytes(reader, valueSize, &valueData), false);
			assertRetVal(ff::Value::CreateData(valueData, value), false);
		}
		break;

	case ff::Value::Type::Dict:
		{
			DWORD valueSize = 0;
			assertRetVal(ff::LoadData(reader, valueSize), false);

			ff::ComPtr<ff::IData> valueData;
			assertRetVal(LoadBytes(reader, valueSize, &valueData), false);

			ff::ComPtr<ff::IDataReader> valueReader;
			assertRetVal(CreateDataReader(valueData, 0, &valueReader), false);

			assertRetVal(ff::Value::CreateDict(value), false);
			assertRetVal(InternalLoadDict(valueReader, (*value)->AsDict()), false);
		}
		break;

	case ff::Value::Type::String:
		{
			ff::String val;
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreateString(val, value), false);
		}
		break;

	case ff::Value::Type::Guid:
		{
			GUID val = GUID_NULL;
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreateGuid(val, value), false);
		}
		break;

	case ff::Value::Type::Point:
		{
			ff::PointInt val(0, 0);
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreatePoint(val, value), false);
		}
		break;

	case ff::Value::Type::Rect:
		{
			ff::RectInt val(0, 0, 0, 0);
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreateRect(val, value), false);
		}
		break;

	case ff::Value::Type::PointF:
		{
			ff::PointFloat val(0, 0);
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreatePointF(val, value), false);
		}
		break;

	case ff::Value::Type::RectF:
		{
			ff::RectFloat val(0, 0, 0, 0);
			assertRetVal(ff::LoadData(reader, val), false);
			assertRetVal(ff::Value::CreateRectF(val, value), false);
		}
		break;

	case ff::Value::Type::DoubleVector:
		{
			DWORD doubleCount = 0;
			assertRetVal(ff::LoadData(reader, doubleCount), false);
			assertRetVal(ff::Value::CreateDoubleVector(value), false);
			(*value)->AsDoubleVector().Reserve(doubleCount);

			for (size_t h = 0; h < doubleCount; h++)
			{
				double val;
				assertRetVal(ff::LoadData(reader, val), false);

				(*value)->AsDoubleVector().Push(val);
			}
		}
		break;

	case ff::Value::Type::FloatVector:
		{
			DWORD floatCount = 0;
			assertRetVal(ff::LoadData(reader, floatCount), false);
			assertRetVal(ff::Value::CreateFloatVector(value), false);
			(*value)->AsFloatVector().Reserve(floatCount);

			for (size_t h = 0; h < floatCount; h++)
			{
				float val;
				assertRetVal(ff::LoadData(reader, val), false);

				(*value)->AsFloatVector().Push(val);
			}
		}
		break;

	case ff::Value::Type::IntVector:
		{
			DWORD intCount = 0;
			assertRetVal(ff::LoadData(reader, intCount), false);
			assertRetVal(ff::Value::CreateIntVector(value), false);
			(*value)->AsIntVector().Reserve(intCount);

			for (size_t h = 0; h < intCount; h++)
			{
				int val;
				assertRetVal(ff::LoadData(reader, val), false);

				(*value)->AsIntVector().Push(val);
			}
		}
		break;

	case ff::Value::Type::DataVector:
		{
			DWORD dataCount = 0;
			assertRetVal(ff::LoadData(reader, dataCount), false);
			assertRetVal(ff::Value::CreateDataVector(value), false);
			(*value)->AsDataVector().Reserve(dataCount);

			for (size_t h = 0; h < dataCount; h++)
			{
				DWORD dataSize = 0;
				assertRetVal(ff::LoadData(reader, dataSize), false);

				ff::ComPtr<ff::IData> valueData;
				assertRetVal(ff::LoadBytes(reader, dataSize, &valueData), false);

				(*value)->AsDataVector().Push(valueData);
			}
		}
		break;

	case ff::Value::Type::StringVector:
		{
			DWORD stringCount = 0;
			assertRetVal(ff::LoadData(reader, stringCount), false);
			assertRetVal(ff::Value::CreateStringVector(value), false);
			(*value)->AsStringVector().Reserve(stringCount);

			for (size_t h = 0; h < stringCount; h++)
			{
				ff::String val;
				assertRetVal(ff::LoadData(reader, val), false);

				(*value)->AsStringVector().Push(val);
			}
		}
		break;

	case ff::Value::Type::ValueVector:
		{
			DWORD valueCount = 0;
			assertRetVal(ff::LoadData(reader, valueCount), false);
			assertRetVal(ff::Value::CreateValueVector(value), false);
			(*value)->AsValueVector().Reserve(valueCount);

			for (size_t h = 0; h < valueCount; h++)
			{
				ff::ValuePtr nestedValue;
				assertRetVal(InternalLoadValue(reader, &nestedValue), false);
				(*value)->AsValueVector().Push(nestedValue);
			}
		}
		break;

	case ff::Value::Type::Object:
		// TODO
		break;
	}

	return true;
}
Esempio n. 8
0
AJ_Status AJ_UnmarshalRaw(AJ_Message* msg, const void** data, size_t len, size_t* actual)
{
    AJ_Status status;
    size_t sz;
    AJ_IOBuffer* ioBuf = &msg->bus->sock.rx;

    /*
     * A soon as we start marshaling raw the header will become invalid so NULL it out
     */
    if (msg->hdr) {
        uint8_t typeId = msg->signature[msg->sigOffset];
        uint8_t pad;
        /*
         * There must be arguments to unmarshal
         */
        if (!typeId) {
            return AJ_ERR_SIGNATURE;
        }
        /*
         * There may be padding before the argument
         */
        pad = PadForType(typeId, ioBuf);
        if (pad > msg->bodyBytes) {
            return AJ_ERR_UNMARSHAL;
        }
        LoadBytes(ioBuf, 0, pad);
        msg->bodyBytes -= pad;
        /*
         * Standard signature matching is now meaningless
         */
        msg->signature = "";
        msg->sigOffset = 0;
        msg->hdr = NULL;
    }
    /*
     * Return an error if caller is attempting read off the end of the body
     */
    if (len > msg->bodyBytes) {
        return AJ_ERR_UNMARSHAL;
    }
    /*
     * We want to return the requested data as contiguous bytes if possible
     */
    sz = AJ_IO_BUF_AVAIL(ioBuf);
    if (sz < len) {
        AJ_IOBufRebase(ioBuf);
    }
    /*
     * If we try to load more than the buffer size we will get an error
     */
    status = LoadBytes(ioBuf, (uint16_t)min(len, ioBuf->bufSize), 0);
    if (status == AJ_OK) {
        sz = AJ_IO_BUF_AVAIL(ioBuf);
        if (sz < len) {
            len = sz;
        }
        *data = ioBuf->readPtr;
        *actual = len;
        ioBuf->readPtr += len;
        msg->bodyBytes -= (uint16_t)len;
    }
    return status;
}
Esempio n. 9
0
AJ_Status AJ_UnmarshalMsg(AJ_BusAttachment* bus, AJ_Message* msg, uint32_t timeout)
{
    AJ_Status status;
    AJ_IOBuffer* ioBuf = &bus->sock.rx;
    uint8_t* endOfHeader;
    uint32_t hdrPad;
    /*
     * Clear message then set the bus
     */
    memset(msg, 0, sizeof(AJ_Message));
    msg->msgId = AJ_INVALID_MSG_ID;
    msg->bus = bus;
    /*
     * Move any unconsumed data to the start of the I/O buffer
     */
    AJ_IOBufRebase(ioBuf);
    /*
     * Load the message header
     */
    while (AJ_IO_BUF_AVAIL(ioBuf) < sizeof(AJ_MsgHeader)) {
        //#pragma calls = AJ_Net_Recv
        status = ioBuf->recv(ioBuf, sizeof(AJ_MsgHeader) - AJ_IO_BUF_AVAIL(ioBuf), timeout);
        if (status != AJ_OK) {
            /*
             * If there were no messages to receive check if we have any methods call that have
             * timed-out and if so generate an internal error message to allow the application to
             * proceed.
             */
            if ((status == AJ_ERR_TIMEOUT) && AJ_TimedOutMethodCall(msg)) {
                msg->hdr = (AJ_MsgHeader*)&internalErrorHdr;
                msg->error = AJ_ErrTimeout;
                msg->sender = AJ_GetUniqueName(msg->bus);
                msg->destination = msg->sender;
                status = AJ_OK;
            }

            return status;
        }
    }
    /*
     * Header was unmarsalled directly into the rx buffer
     */
    msg->hdr = (AJ_MsgHeader*)ioBuf->bufStart;
    ioBuf->readPtr += sizeof(AJ_MsgHeader);
    /*
     * Quick sanity check on the header - unrecoverable error if this check fails
     */
    if ((msg->hdr->endianess != AJ_LITTLE_ENDIAN) && (msg->hdr->endianess != AJ_BIG_ENDIAN)) {
        return AJ_ERR_READ;
    }
    /*
     * Endian swap header info - conventiently they are contiguous in the header
     */
    EndianSwap(msg, AJ_ARG_INT32, &msg->hdr->bodyLen, 3);
    msg->bodyBytes = msg->hdr->bodyLen;
    /*
     * The header is null padded to an 8 bytes boundary
     */
    hdrPad = (8 - msg->hdr->headerLen) & 7;
    /*
     * Load the header
     */
    status = LoadBytes(ioBuf, msg->hdr->headerLen + hdrPad, 0);
    if (status != AJ_OK) {
        return status;
    }
#ifndef NDEBUG
    /*
     * Check that messages are getting closed
     */
    AJ_ASSERT(!currentMsg);
    currentMsg = msg;
#endif
    /*
     * Assume an empty signature
     */
    msg->signature = "";
    /*
     * We have the header in the buffer now we can unmarshal the header fields
     */
    endOfHeader = ioBuf->bufStart + sizeof(AJ_MsgHeader) + msg->hdr->headerLen;
    while (ioBuf->readPtr < endOfHeader) {
        const char* fieldSig;
        uint8_t fieldId;
        AJ_Arg hdrVal;
        /*
         * Custom unmarshal the header field - signature is "(yv)" so starts off with STRUCT aligment.
         */
        status = LoadBytes(ioBuf, 4, PadForType(AJ_ARG_STRUCT, ioBuf));
        if (status != AJ_OK) {
            break;
        }
        fieldId = ioBuf->readPtr[0];
        fieldSig = (const char*)&ioBuf->readPtr[2];
        ioBuf->readPtr += 4;
        /*
         * Now unmarshal the field value
         */
        status = Unmarshal(msg, &fieldSig, &hdrVal);
        if (status != AJ_OK) {
            break;
        }
        /*
         * Check the field has the type we expect - we ignore fields we don't know
         */
        if ((fieldId <= AJ_HDR_SESSION_ID) && (TypeForHdr[fieldId] != hdrVal.typeId)) {
            status = AJ_ERR_UNMARSHAL;
            break;
        }
        /*
         * Set the field value in the message
         */
        switch (fieldId) {
        case AJ_HDR_OBJ_PATH:
            msg->objPath = hdrVal.val.v_objPath;
            break;

        case AJ_HDR_INTERFACE:
            msg->iface = hdrVal.val.v_string;
            break;

        case AJ_HDR_MEMBER:
            msg->member = hdrVal.val.v_string;
            break;

        case AJ_HDR_ERROR_NAME:
            msg->error = hdrVal.val.v_string;
            break;

        case AJ_HDR_REPLY_SERIAL:
            msg->replySerial = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_DESTINATION:
            msg->destination = hdrVal.val.v_string;
            break;

        case AJ_HDR_SENDER:
            msg->sender = hdrVal.val.v_string;
            break;

        case AJ_HDR_SIGNATURE:
            msg->signature = hdrVal.val.v_signature;
            break;

        case AJ_HDR_TIMESTAMP:
            msg->timestamp = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_TIME_TO_LIVE:
            msg->ttl = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_SESSION_ID:
            msg->sessionId = *(hdrVal.val.v_uint32);
            break;

        case AJ_HDR_HANDLES:
        case AJ_HDR_COMPRESSION_TOKEN:
        default:
            /* Ignored */
            break;
        }
    }
    if (status == AJ_OK) {
        AJ_ASSERT(ioBuf->readPtr == endOfHeader);
        /*
         * Consume the header pad bytes.
         */
        ioBuf->readPtr += hdrPad;
        /*
         * If the message is encrypted load the entire message body and decrypt it.
         */
        if (msg->hdr->flags & AJ_FLAG_ENCRYPTED) {
            status = LoadBytes(ioBuf, msg->hdr->bodyLen, 0);
            if (status == AJ_OK) {
                status = DecryptMessage(msg);
            }
        }
        /*
         * Toggle the AUTO_START flag so in the API no flags == 0
         *
         * Note we must do this after decrypting the message or message authentication will fail.
         */
        msg->hdr->flags ^= AJ_FLAG_AUTO_START;
        /*
         * If the message looks good try to identify it.
         */
        if (status == AJ_OK) {
            status = AJ_IdentifyMessage(msg);
        }
    } else {
        /*
         * Consume entire header
         */
        ioBuf->readPtr = endOfHeader + hdrPad;
    }
    if (status == AJ_OK) {
        AJ_DumpMsg("RECEIVED", msg, FALSE);
    } else {
        /*
         * Silently discard message unless in debug mode
         */
        AJ_ErrPrintf(("Discarding bad message %s\n", AJ_StatusText(status)));
        AJ_DumpMsg("DISCARDING", msg, FALSE);
        AJ_CloseMsg(msg);
    }

    return status;
}
Esempio n. 10
0
/*
 * Unmarshal a single argument
 */
static AJ_Status Unmarshal(AJ_Message* msg, const char** sig, AJ_Arg* arg)
{
    AJ_Status status;
    AJ_IOBuffer* ioBuf = &msg->bus->sock.rx;
    char typeId;
    uint32_t pad;
    uint32_t sz;

    memset(arg, 0, sizeof(AJ_Arg));

    if (!*sig || !**sig) {
        return AJ_ERR_END_OF_DATA;
    }

    typeId = **sig;
    *sig += 1;
    pad = PadForType(typeId, ioBuf);

    if (IsScalarType(typeId)) {
        sz = SizeOfType(typeId);
        status = LoadBytes(ioBuf, sz, pad);
        if (status != AJ_OK) {
            return status;
        }
        /*
         * For numeric types we just return a pointer into the buffer
         */
        arg->typeId = typeId;
        arg->val.v_byte = ioBuf->readPtr;
        arg->len = 0;
        ioBuf->readPtr += sz;
        EndianSwap(msg, typeId, (void*)arg->val.v_data, 1);
    } else if (TYPE_FLAG(typeId) & (AJ_STRING | AJ_VARIANT)) {
        /*
         * Length field for a signature is 1 byte, for regular strings its 4 bytes
         */
        uint32_t lenSize = ALIGNMENT(typeId);
        /*
         * Read the string length. Note the length doesn't include the terminating NUL
         * so an empty string in encoded as two zero bytes.
         */
        status = LoadBytes(ioBuf, lenSize, pad);
        if (status != AJ_OK) {
            return status;
        }
        if (lenSize == 4) {
            EndianSwap(msg, AJ_ARG_UINT32, ioBuf->readPtr, 1);
            sz = *((uint32_t*)ioBuf->readPtr);
        } else {
            sz = (uint32_t)(*ioBuf->readPtr);
        }
        ioBuf->readPtr += lenSize;
        status = LoadBytes(ioBuf, sz + 1, 0);
        if (status != AJ_OK) {
            return status;
        }
        arg->typeId = typeId;
        arg->len = sz;
        arg->val.v_string = (char*)ioBuf->readPtr;
        ioBuf->readPtr += sz + 1;
        /*
         * If unmarshalling a variant store offset to start of signature
         */
        if (typeId == AJ_ARG_VARIANT) {
            msg->varOffset = (uint8_t)(sz + 1);
        }
    } else if (typeId == AJ_ARG_ARRAY) {
        status = UnmarshalArray(msg, sig, arg, pad);
    } else if ((typeId == AJ_ARG_STRUCT) || (typeId == AJ_ARG_DICT_ENTRY)) {
        arg->typeId = typeId;
        status = UnmarshalStruct(msg, sig, arg, pad);
    } else {
        status = AJ_ERR_UNMARSHAL;
    }
    return status;
}