static AJ_Status MarshalContainer(AJ_Message* msg, const char** sig, AJ_Arg* arg, uint8_t pad) { AJ_Status status; AJ_IOBuffer* ioBuf = &msg->bus->sock.tx; *sig -= 1; arg->sigPtr = *sig + 1; if (**sig == AJ_ARG_ARRAY) { /* * Reserve space for the length and save a pointer to it */ status = WriteBytes(msg, NULL, 0, pad + 4); arg->val.v_data = ioBuf->writePtr - 4; /* * Might need to pad if the elements align on an 8 byte boundary */ if (status == AJ_OK) { status = WritePad(msg, PadForType(arg->sigPtr[0], ioBuf)); } } else { status = WritePad(msg, pad); } /* * Consume container signature */ *sig += CompleteTypeSigLen(*sig); return status; }
bool ZFile::WriteAlignedString(const ZString& str) { int length = str.GetLength() + 1; if (Write((void*)(PCC)str, str.GetLength() + 1) != 0) { return WritePad(length); } return false; }
AJ_Status AJ_DeliverMsgPartial(AJ_Message* msg, uint32_t bytesRemaining) { AJ_IOBuffer* ioBuf = &msg->bus->sock.tx; uint8_t typeId = msg->signature[msg->sigOffset]; size_t pad; AJ_ASSERT(!msg->outer); if (!msg->hdr || !bytesRemaining) { return AJ_ERR_UNEXPECTED; } /* * Partial delivery not currently supported for messages that must be encrypted. */ if (msg->hdr->flags & AJ_FLAG_ENCRYPTED) { return AJ_ERR_SECURITY; } /* * There must be arguments to marshal */ if (!typeId) { return AJ_ERR_SIGNATURE; } /* * Pad to the start of the argument. */ pad = PadForType(typeId, ioBuf); if (pad) { AJ_Status status = WritePad(msg, pad); if (status != AJ_OK) { return status; } } /* * Set the body length in the header buffer. */ msg->hdr->bodyLen = (uint32_t)(msg->bodyBytes + pad + bytesRemaining); AJ_DumpMsg("SENDING(partial)", msg, FALSE); /* * The buffer space occupied by the header is going to be overwritten * so the header is going to become invalid. */ msg->hdr = NULL; /* * From now on we are going to count down the remaining body bytes */ msg->bodyBytes = (uint32_t)bytesRemaining; /* * Standard signature matching is now meaningless */ msg->signature = ""; msg->sigOffset = 0;; return AJ_OK; }
static AJ_Status MarshalMsg(AJ_Message* msg, uint8_t msgType, uint32_t msgId, uint8_t flags) { AJ_Status status = AJ_OK; AJ_IOBuffer* ioBuf = &msg->bus->sock.tx; uint8_t fieldId; uint8_t secure = FALSE; /* * Use the msgId to lookup information in the object and interface descriptions to * initialize the message header fields. */ status = AJ_InitMessageFromMsgId(msg, msgId, msgType, &secure); if (status != AJ_OK) { return status; } AJ_IO_BUF_RESET(ioBuf); msg->hdr = (AJ_MsgHeader*)ioBuf->bufStart; memset(msg->hdr, 0, sizeof(AJ_MsgHeader)); ioBuf->writePtr += sizeof(AJ_MsgHeader); msg->hdr->endianess = HOST_ENDIANESS; msg->hdr->msgType = msgType; msg->hdr->flags = flags; if (secure) { msg->hdr->flags |= AJ_FLAG_ENCRYPTED; } /* * The wire-protocol calls this flag NO_AUTO_START we toggle the meaning in the API * so the default flags value can be zero. */ msg->hdr->flags ^= AJ_FLAG_AUTO_START; /* * Serial number cannot be zero (wire-spec wierdness) */ do { msg->hdr->serialNum = msg->bus->serial++; } while (msg->bus->serial == 1); /* * Marshal the header fields */ for (fieldId = AJ_HDR_OBJ_PATH; fieldId <= AJ_HDR_SESSION_ID; ++fieldId) { char typeId = TypeForHdr[fieldId]; char buf[4]; const char* fieldSig = &buf[2]; AJ_Arg hdrVal; /* * Skip field id's that are not currently used. */ if (typeId == AJ_ARG_INVALID) { continue; } InitArg(&hdrVal, typeId, NULL); switch (fieldId) { case AJ_HDR_OBJ_PATH: if ((msgType == AJ_MSG_METHOD_CALL) || (msgType == AJ_MSG_SIGNAL)) { hdrVal.val.v_objPath = msg->objPath; } break; case AJ_HDR_INTERFACE: hdrVal.val.v_string = msg->iface; break; case AJ_HDR_MEMBER: if (msgType != AJ_MSG_ERROR) { int32_t len = AJ_StringFindFirstOf(msg->member, " "); hdrVal.val.v_string = msg->member; hdrVal.len = (len >= 0) ? len : 0; } break; case AJ_HDR_ERROR_NAME: if (msgType == AJ_MSG_ERROR) { hdrVal.val.v_string = msg->error; } break; case AJ_HDR_REPLY_SERIAL: if ((msgType == AJ_MSG_METHOD_RET) || (msgType == AJ_MSG_ERROR)) { hdrVal.val.v_uint32 = &msg->replySerial; } break; case AJ_HDR_DESTINATION: hdrVal.val.v_string = msg->destination; break; case AJ_HDR_SENDER: hdrVal.val.v_string = AJ_GetUniqueName(msg->bus); break; case AJ_HDR_SIGNATURE: hdrVal.val.v_signature = msg->signature; break; case AJ_HDR_TIMESTAMP: if (msg->ttl) { AJ_Time timer; timer.seconds = 0; timer.milliseconds = 0; msg->timestamp = AJ_GetElapsedTime(&timer, FALSE); hdrVal.val.v_uint32 = &msg->timestamp; } break; case AJ_HDR_TIME_TO_LIVE: if (msg->ttl) { hdrVal.val.v_uint32 = &msg->ttl; } break; case AJ_HDR_SESSION_ID: if (msg->sessionId) { hdrVal.val.v_uint32 = &msg->sessionId; } break; case AJ_HDR_HANDLES: case AJ_HDR_COMPRESSION_TOKEN: default: continue; } /* * Ignore empty fields. */ if (!hdrVal.val.v_data) { continue; } /* * Custom marshal the header field - signature is "(yv)" so starts off with STRUCT aligment. */ buf[0] = fieldId; buf[1] = 1; buf[2] = typeId; buf[3] = 0; WriteBytes(msg, buf, 4, PadForType(AJ_ARG_STRUCT, ioBuf)); /* * Now marshal the field value */ Marshal(msg, &fieldSig, &hdrVal); } if (status == AJ_OK) { /* * Write the header length */ msg->hdr->headerLen = (uint32_t)((ioBuf->writePtr - ioBuf->bufStart) - sizeof(AJ_MsgHeader)); /* * Header must be padded to an 8 byte boundary */ status = WritePad(msg, (8 - msg->hdr->headerLen) & 7); } return status; }
static AJ_Status Marshal(AJ_Message* msg, const char** sig, AJ_Arg* arg) { AJ_Status status = AJ_OK; AJ_IOBuffer* ioBuf = &msg->bus->sock.tx; char typeId = **sig; uint32_t pad = PadForType(typeId, ioBuf); size_t sz; if (!arg) { return AJ_ERR_NULL; } *sig += 1; if (IsScalarType(arg->typeId)) { if (arg->flags & AJ_ARRAY_FLAG) { if ((typeId != AJ_ARG_ARRAY) || (**sig != arg->typeId)) { return AJ_ERR_MARSHAL; } *sig += 1; sz = arg->len; status = WriteBytes(msg, &sz, 4, pad); if (status == AJ_OK) { /* * May need to pad if the elements required 8 byte alignment */ pad = PadForType(arg->typeId, ioBuf); } } else { if (typeId != arg->typeId) { return AJ_ERR_MARSHAL; } sz = SizeOfType(typeId); } if (status == AJ_OK) { status = WriteBytes(msg, arg->val.v_data, sz, pad); } } else if (TYPE_FLAG(typeId) & (AJ_STRING | AJ_VARIANT)) { if (typeId != arg->typeId) { return AJ_ERR_MARSHAL; } sz = arg->len ? arg->len : strlen(arg->val.v_string); /* * Length field for a signature is 1 byte, for regular strings its 4 bytes */ if (ALIGNMENT(typeId) == 1) { uint8_t szu8 = (uint8_t)sz; if (sz > 255) { return AJ_ERR_MARSHAL; } status = WriteBytes(msg, &szu8, 1, pad); } else { status = WriteBytes(msg, &sz, 4, pad); } if (status == AJ_OK) { status = WriteBytes(msg, arg->val.v_string, sz, 0); /* * String must be NUL terminated on the wire */ if (status == AJ_OK) { status = WritePad(msg, 1); } /* * If marshalling a variant store offset to start of signature */ if (typeId == AJ_ARG_VARIANT) { msg->varOffset = (uint8_t)(sz + 1); } } } else if (TYPE_FLAG(typeId) & AJ_CONTAINER) { if (typeId != arg->typeId) { return AJ_ERR_MARSHAL; } status = MarshalContainer(msg, sig, arg, pad); } else { return AJ_ERR_MARSHAL; } return status; }