/usr/include/x86_64-linux-gnu/alljoyn/MsgArg.h is in liballjoyn-dev-1604 16.04a-3.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 | #ifndef _ALLJOYN_MSGARG_H
#define _ALLJOYN_MSGARG_H
/**
* @file
* This file defines a class for message bus data types and values
*/
/******************************************************************************
* Copyright AllSeen Alliance. All rights reserved.
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
******************************************************************************/
#ifndef __cplusplus
#error Only include MsgArg.h in C++ code.
#endif
#include <qcc/platform.h>
#include <qcc/String.h>
#include <stdarg.h>
#include <alljoyn/Status.h>
namespace ajn {
/**
* Forward definitions
*/
class MsgArg;
/**
* Enumeration of the various message arg types.
* @remark Most of these map directly to the values used in the
* DBus wire protocol but some are specific to the AllJoyn implementation.
*/
typedef enum {
ALLJOYN_INVALID = 0, ///< AllJoyn INVALID typeId
ALLJOYN_ARRAY = 'a', ///< AllJoyn array container type
ALLJOYN_BOOLEAN = 'b', ///< AllJoyn boolean basic type, @c 0 is @c FALSE and @c 1 is @c TRUE - Everything else is invalid
ALLJOYN_DOUBLE = 'd', ///< AllJoyn IEEE 754 double basic type
ALLJOYN_DICT_ENTRY = 'e', ///< AllJoyn dictionary or map container type - an array of key-value pairs
ALLJOYN_SIGNATURE = 'g', ///< AllJoyn signature basic type
ALLJOYN_HANDLE = 'h', ///< AllJoyn socket handle basic type
ALLJOYN_INT32 = 'i', ///< AllJoyn 32-bit signed integer basic type
ALLJOYN_INT16 = 'n', ///< AllJoyn 16-bit signed integer basic type
ALLJOYN_OBJECT_PATH = 'o', ///< AllJoyn Name of an AllJoyn object instance basic type
ALLJOYN_UINT16 = 'q', ///< AllJoyn 16-bit unsigned integer basic type
ALLJOYN_STRUCT = 'r', ///< AllJoyn struct container type
ALLJOYN_STRING = 's', ///< AllJoyn UTF-8 NULL terminated string basic type
ALLJOYN_UINT64 = 't', ///< AllJoyn 64-bit unsigned integer basic type
ALLJOYN_UINT32 = 'u', ///< AllJoyn 32-bit unsigned integer basic type
ALLJOYN_VARIANT = 'v', ///< AllJoyn variant container type
ALLJOYN_INT64 = 'x', ///< AllJoyn 64-bit signed integer basic type
ALLJOYN_BYTE = 'y', ///< AllJoyn 8-bit unsigned integer basic type
ALLJOYN_STRUCT_OPEN = '(', /**< Never actually used as a typeId: specified as ALLJOYN_STRUCT */
ALLJOYN_STRUCT_CLOSE = ')', /**< Never actually used as a typeId: specified as ALLJOYN_STRUCT */
ALLJOYN_DICT_ENTRY_OPEN = '{', /**< Never actually used as a typeId: specified as ALLJOYN_DICT_ENTRY */
ALLJOYN_DICT_ENTRY_CLOSE = '}', /**< Never actually used as a typeId: specified as ALLJOYN_DICT_ENTRY */
ALLJOYN_BOOLEAN_ARRAY = ('b' << 8) | 'a', ///< AllJoyn array of booleans
ALLJOYN_DOUBLE_ARRAY = ('d' << 8) | 'a', ///< AllJoyn array of IEEE 754 doubles
ALLJOYN_INT32_ARRAY = ('i' << 8) | 'a', ///< AllJoyn array of 32-bit signed integers
ALLJOYN_INT16_ARRAY = ('n' << 8) | 'a', ///< AllJoyn array of 16-bit signed integers
ALLJOYN_UINT16_ARRAY = ('q' << 8) | 'a', ///< AllJoyn array of 16-bit unsigned integers
ALLJOYN_UINT64_ARRAY = ('t' << 8) | 'a', ///< AllJoyn array of 64-bit unsigned integers
ALLJOYN_UINT32_ARRAY = ('u' << 8) | 'a', ///< AllJoyn array of 32-bit unsigned integers
ALLJOYN_INT64_ARRAY = ('x' << 8) | 'a', ///< AllJoyn array of 64-bit signed integers
ALLJOYN_BYTE_ARRAY = ('y' << 8) | 'a', ///< AllJoyn array of 8-bit unsigned integers
ALLJOYN_WILDCARD = '*' ///< This never appears in a signature but is used for matching arbitrary message args
} AllJoynTypeId;
/**
* Type for initializing an invalid MsgArg
*/
typedef struct {
void* unused[3]; /**< Fields for zero-initializing an invalid MsgArg */
} AllJoynInvalid;
/**
* Type for the various string types
*/
typedef struct {
uint32_t len; /**< Length of AllJoynString */
const char* str; /**< The actual string */
} AllJoynString;
/**
* Type for a signature
* The same as AllJoynString except the length is a single byte (thus signatures have a maximum length of 255).
* The content must be a valid signature.
*/
typedef struct {
uint8_t len; /**< Length of AllJoyn signature */
const char* sig; /**< The signature */
} AllJoynSignature;
/**
* Type for an array
*/
class AllJoynArray {
friend class MsgArg;
friend class SignatureUtils;
friend class _Message;
public:
/**
* Set the array value. Note that arrays must be initialized using this function otherwise they
* cannot be marshaled.
*
* @param elemSig The signature for the array element type.
* @param numElements The size of the array.
* @param elements Pointer to an array of MsgArgs for the elements. Must be NULL if numElements
* is zero. This array must be dynamically allocated because it will be
* deleted when the MsgArg destructor is called.
*
* @return ER_OK if the array was successfully initialized.
*/
QStatus SetElements(const char* elemSig, size_t numElements, MsgArg* elements);
/**
* Accessor function to return the number of array elements
*
* @return The number of array elements
*/
size_t GetNumElements() const { return numElements; }
/**
* Accessor function to return the number of array elements
*
* @return The array elements
*/
const MsgArg* GetElements() const { return elements; }
/**
* Accessor function to return the array element signature.
*
* @return The array element signature or an empty string.
*/
const char* GetElemSig() const { return elemSig ? elemSig : ""; }
private:
char* elemSig; /**< Element signature */
size_t numElements; /**< Number of elements in the AllJoyn array */
MsgArg* elements; /**< Pointer to array */
};
/**
* Type for a variant
*/
typedef struct {
MsgArg* val; /**< Pointer to value of type MsgArg*/
} AllJoynVariant;
/**
* Type for a struct
*/
typedef struct {
size_t numMembers; /**< Number of members in structure */
MsgArg* members; /**< Pointer to members of the structure */
} AllJoynStruct;
/**
* Type for a handle. A handle is an abstraction of a platform-specific socket or file descriptor.
*
* @note Handles associated with in a message received by the application will be closed when the
* message destructor is called or when a method call is converted into a method reply. If the
* application code needs to continue using the handle the handle must be duplicated by calling
* qcc:SocketDup() or the appropriate platform-specific APIs. Handles that are passed in when
* creating a message to be sent are duplicated internally and can be closed by the caller after the
* message has been created. Handles that have been duplicated using qcc::SocketDup() must be closed
* by calling qcc::Close(). Handles duplicated by calling a native platform "dup" API must be closed
* using the native "close" API.
*/
typedef struct {
qcc::SocketFd fd; /**< A platform-specific socket file descriptor */
} AllJoynHandle;
/**
* Type for a dictionary entry
*/
typedef struct {
MsgArg* key; /**< Key in the dictionary entry */
MsgArg* val; /**< Value in the dictionary entry */
} AllJoynDictEntry;
/**
* Type for arrays of scalars
*/
typedef struct {
size_t numElements; /**< Number of elements in the AllJoynScalar Array */
union {
const uint8_t* v_byte;
const int16_t* v_int16;
const uint16_t* v_uint16;
const bool* v_bool;
const uint32_t* v_uint32;
const int32_t* v_int32;
const int64_t* v_int64;
const uint64_t* v_uint64;
const double* v_double;
};
} AllJoynScalarArray;
/**
* Class definition for a message arg.
* This class deals with the message bus types and the operations on them
*
* MsgArgs are designed to be light-weight. A MsgArg will normally hold references to the data
* (strings etc.) it wraps and will only copy that data if the MsgArg is assigned. For example no
* additional memory is allocated for an #ALLJOYN_STRING that references an existing const char*.
* If a MsgArg is assigned the destination receives a copy of the contents of the source. The
* Stabilize() methods can also be called to explicitly force contents of the MsgArg to be copied.
*
* See [Message argument or MsgArg](@ref msg_argument_or_msgarg)
*/
class MsgArg {
friend class _Message;
friend class MsgArgUtils;
public:
/**
* The flag value that indicates that the MsgArg owns the data it references so is responsible
* for freeing that data in the destructor. This applies to any MsgArg that has a pointer to a
* string or other data.
* @return value that indicates the MsgArg owns the data.
*/
static const uint8_t OwnsData = 1;
/**
* The flag value that indicates that the MsgArg owns the nested MsgArgs it references so is responsible
* for freeing those MsgArgs in the destructor. This applies to MsgArgs of type #ALLJOYN_ARRAY,
* #ALLJOYN_STRUCT, #ALLJOYN_DICT_ENTRY, and #ALLJOYN_VARIANT.
* @return value that indicates the MsgArg owns the nested MsgArgs it references.
*/
static const uint8_t OwnsArgs = 2;
/**
* The type of this arg
*/
AllJoynTypeId typeId;
/**
* Union of the various argument values
*/
union {
uint8_t v_byte;
int16_t v_int16;
uint16_t v_uint16;
bool v_bool;
uint32_t v_uint32;
int32_t v_int32;
int64_t v_int64;
uint64_t v_uint64;
double v_double;
AllJoynString v_string;
AllJoynString v_objPath;
AllJoynSignature v_signature;
AllJoynHandle v_handle;
AllJoynArray v_array;
AllJoynStruct v_struct;
AllJoynDictEntry v_dictEntry;
AllJoynVariant v_variant;
AllJoynScalarArray v_scalarArray;
AllJoynInvalid v_invalid;
};
/**
* Returns a string for the signature of this value
*
* @return The signature string for this MsgArg
*/
qcc::String Signature() const { return Signature(this, 1); }
/**
* Returns a string representation of the signature of an array of message args.
*
* @param values A pointer to an array of message arg values
* @param numValues Length of the array
*
* @return The signature string for the message args.
*/
static qcc::String AJ_CALL Signature(const MsgArg* values, size_t numValues);
/**
* Returns an XML string representation of this type
*
* @param indent Number of spaces to indent the generated xml
*
* @return The XML string
*/
qcc::String ToString(size_t indent = 0) const;
/**
* Returns an XML string representation for an array of message args.
*
* @param args The message arg array.
* @param numArgs The size of the message arg array.
* @param indent Number of spaces to indent the generated xml
*
* @return The XML string representation of the message args.
*/
static qcc::String AJ_CALL ToString(const MsgArg* args, size_t numArgs, size_t indent = 0);
/**
* Checks the signature of this arg.
*
* @param signature The signature to check
*
* @return true if this arg has the specified signature, otherwise returns false.
*/
bool HasSignature(const char* signature) const;
/**
* Assignment operator
*
* @param other The source MsgArg for the assignment
*
* @return The assigned MsgArg
*/
MsgArg& operator=(const MsgArg& other) {
if (this != &other) {
Clone(*this, other);
}
return *this;
}
/**
* Copy constructor
*
* @param other The source MsgArg for the copy
*/
MsgArg(const MsgArg& other) : typeId(ALLJOYN_INVALID) { Clone(*this, other); }
/**
* Destructor
*/
virtual ~MsgArg() { Clear(); }
/**
* Constructor
*
* @param typeId The type for the MsgArg
*/
MsgArg(AllJoynTypeId typeId) : typeId(typeId), flags(0) { v_invalid.unused[0] = v_invalid.unused[1] = v_invalid.unused[2] = NULL; }
/**
* Constructor to build a message arg. If the constructor fails for any reason the type will be
* set to #ALLJOYN_INVALID. See the description of the #Set() method for information about the
* signature and parameters. For initializing complex values it is recommended to use the
* default constructor and the #Set() method so the success of setting the value can be
* explicitly checked.
*
* @param signature The signature for MsgArg value.
* @param ... One or more values to initialize the MsgArg.
*/
MsgArg(const char* signature, ...);
/**
* Set value of a message arg from a signature and a list of values. Note that any values or
* MsgArg pointers passed in must remain valid until this MsgArg is freed.
*
* - @c 'a' The array length followed by:
* - If the element type is a basic type a pointer to an array of values of that type.
* - If the element type is string a pointer to array of const char*,
* - If the element type is an @ref ALLJOYN_ARRAY "ARRAY", @ref ALLJOYN_STRUCT "STRUCT",
* @ref ALLJOYN_DICT_ENTRY "DICT_ENTRY" or @ref ALLJOYN_VARIANT "VARIANT" a pointer to an
* array of MsgArgs where each MsgArg has the signature specified by the element type.
* - If the element type is specified using the wildcard character '*', a pointer to
* an array of MsgArgs. The array element type is determined from the type of the
* first MsgArg in the array, all the elements must have the same type.
* - If the element type is specified using a '$' character, a pointer to an array of
* qcc::String. This is a convenience case for initializing a string array, actual
* signature "as" from a qcc::String array.
* - @c 'b' A bool value
* - @c 'd' A double (64 bits)
* - @c 'g' A pointer to a NUL terminated string (pointer must remain valid for lifetime of the MsgArg)
* - @c 'h' A qcc::SocketFd
* - @c 'i' An int (32 bits)
* - @c 'n' An int (16 bits)
* - @c 'o' A pointer to a NUL terminated string (pointer must remain valid for lifetime of the MsgArg)
* - @c 'q' A uint (16 bits)
* - @c 's' A pointer to a NUL terminated string (pointer must remain valid for lifetime of the MsgArg)
* - @c 't' A uint (64 bits)
* - @c 'u' A uint (32 bits)
* - @c 'v' Not allowed, the actual type must be provided.
* - @c 'x' An int (64 bits)
* - @c 'y' A byte (8 bits)
*
* - @c '(' and @c ')' The list of values that appear between the parentheses using the notation above
* - @c '{' and @c '}' A pair values using the notation above.
*
* - @c '*' A pointer to a MsgArg.
*
* Examples:
*
* An array of strings
*
* @code
* char* fruits[3] = { "apple", "banana", "orange" };
* MsgArg bowl;
* bowl.Set("as", 3, fruits);
* @endcode
*
* A struct with a uint and two string elements.
*
* @code arg.Set("(uss)", 1024, "hello", "world"); @endcode
*
* An array of 3 dictionary entries where each entry has an integer key and string value.
*
* @code
* MsgArg dict[3];
* dict[0].Set("{is}", 1, "red");
* dict[1].Set("{is}", 2, "green");
* dict[2].Set("{is}", 3, "blue");
* arg.Set("a{is}", 3, dict);
* @endcode
*
* An array of uint_16's
*
* @code
* uint16_t aq[] = { 1, 2, 3, 5, 6, 7 };
* arg.Set("aq", sizeof(aq) / sizeof(uint16_t), aq);
* @endcode
*
* @param signature The signature for MsgArg value
* @param ... One or more values to initialize the MsgArg.
*
* @return
* - #ER_OK if the MsgArg was successfully set
* - An error status otherwise
*/
QStatus Set(const char* signature, ...);
/**
* Set an array of MsgArgs by applying the Set() method to each MsgArg in turn.
*
* @param args An array of MsgArgs to set.
* @param numArgs [in,out] On input the size of the args array. On output the number of MsgArgs
* that were set. There must be at least enough MsgArgs to completely
* initialize the signature.
*
* @param signature The signature for MsgArg values
* @param ... One or more values to initialize the MsgArg list.
*
* @return
* - #ER_OK if the MsgArgs were successfully set.
* - #ER_BUS_TRUNCATED if the signature was longer than expected.
* - Other error status codes indicating a failure.
*/
static QStatus AJ_CALL Set(MsgArg* args, size_t& numArgs, const char* signature, ...);
/**
* Matches a signature to the MsArg and if the signature matches unpacks the component values of a MsgArg. Note that the values
* returned are references into the MsgArg itself so unless copied will become invalid if the MsgArg is freed or goes out of scope.
* This function resolved through variants, so if the MsgArg is a variant that references a 32 bit integer is can be unpacked
* directly into a 32 bit integer pointer.
*
* - @c 'a' A pointer to a length of type size_t that returns the number of elements in the array followed by:
* - If the element type is a scalar type a pointer to a pointer of the correct type for the values.
* - Otherwise a pointer to a pointer to a MsgArg.
*
* - @c 'b' A pointer to a bool
* - @c 'd' A pointer to a double (64 bits)
* - @c 'g' A pointer to a char* (character string is valid for the lifetime of the MsgArg)
* - @c 'h' A pointer to a qcc::SocketFd
* - @c 'i' A pointer to an int32_t
* - @c 'n' A pointer to an int16_t
* - @c 'o' A pointer to a char* (character string is valid for the lifetime of the MsgArg)
* - @c 'q' A pointer to a uint16_t
* - @c 's' A pointer to a char* (character string is valid for the lifetime of the MsgArg)
* - @c 't' A pointer to a uint64_t
* - @c 'u' A pointer to a uint32_t
* - @c 'v' A pointer to a pointer to a MsgArg, matches to a variant but returns a pointer to
* the MsgArg of the underlying real type.
* - @c 'x' A pointer to an int64_t
* - @c 'y' A pointer to a uint8_t
*
* - @c '(' and @c ')' A list of pointers as required for each of the struct members.
* - @c '{' and @c '}' Pointers as required for the key and value members.
*
* - @c '*' A pointer to a pointer to a MsgArg. This matches any value type.
*
* Examples:
*
* A struct with and uint32 and two string elements.
*
* @code
* struct {
* uint32_t i;
* char *hello;
* char *world;
* } myStruct;
* arg.Get("(uss)", &myStruct.i, &myStruct.hello, &myStruct.world);
* @endcode
*
* A variant where it is known that the value is a uint32, a string, or double. Note that the
* variant is resolved away.
*
* @code
* uint32_t i;
* double d;
* char *str;
* QStatus status = arg.Get("i", &i);
* if (status == ER_BUS_SIGNATURE_MISMATCH) {
* status = arg.Get("s", &str);
* if (status == ER_BUS_SIGNATURE_MISMATCH) {
* status = arg.Get("d", &d);
* }
* }
* @endcode
*
* An array of dictionary entries where each entry has an integer key and variant. Find the
* entries where the variant value is a string or a struct of 2 strings.
*
* @code
* MsgArg *entries;
* size_t num;
* arg.Get("a{iv}", &num, &entries);
* for (size_t i = 0; i > num; ++i) {
* char *str1;
* char *str2;
* uint32_t key;
* status = entries[i].Get("{is}", &key, &str1);
* if (status == ER_BUS_SIGNATURE_MISMATCH) {
* status = entries[i].Get("{i(ss)}", &key, &str1, &str2);
* }
* }
* @endcode
*
* An array of uint_16's
*
* @code
* uint16_t *vals;
* size_t numVals;
* arg.Get("aq", &numVals, &vals);
* @endcode
*
* @param signature The signature for MsgArg value
* @param ... Pointers to return the unpacked values.
*
* @return
* - #ER_OK if the signature matched and MsgArg was successfully unpacked.
* - #ER_BUS_SIGNATURE_MISMATCH if the signature did not match.
* - An error status otherwise
*/
QStatus Get(const char* signature, ...) const;
/**
* Unpack an array of MsgArgs by applying the Get() method to each MsgArg in turn.
*
* @param args An array of MsgArgs to unpack.
* @param numArgs The size of the MsgArgs array.
* @param signature The signature to match against the MsgArg values
* @param ... Pointers to return references to the unpacked values.
*
* @return
* - #ER_OK if the MsgArgs were successfully set.
* - #ER_BUS_SIGNATURE_MISMATCH if the signature did not match.
* - Other error status codes indicating a failure.
*/
static QStatus AJ_CALL Get(const MsgArg* args, size_t numArgs, const char* signature, ...);
/**
* Helper function for accessing dictionary elements. The MsgArg must be an array of dictionary
* elements. The second parameter is the key value, this is expressed according to the rules for
* MsgArg::Set so is either a scalar, a pointer to a string, or for 64 bit values a pointer to
* the value. This value is matched against the dictionary array to locate the matching element.
* The third and subsequent parameters are unpacked according to the rules of MsgArg::Get.
*
* For example, where the key is a string and the values are structs:
*
* @code
* uint8_t age;
* uint32_t height;
* const char* address;
* QStatus status = arg.GetElement("{s(yus)}", "fred", &age, &height, &address);
* @endcode
*
* This function is particularly useful for extracting specific properties from the array of property
* values returned by ProxyBusObject::GetAllProperties.
*
* @param elemSig The expected signature for the dictionary element, e.g. "{su}"
* @param ... Pointers to return unpacked key values.
*
* @return
* - #ER_OK if the dictionary signature matched and MsgArg was successfully unpacked.
* - #ER_BUS_NOT_A_DICTIONARY if this method is called on a MsgArg that is not a dictionary.
* - #ER_BUS_SIGNATURE_MISMATCH if the signature did not match.
* - #ER_BUS_ELEMENT_NOT_FOUND if the key was not found in the dictionary.
* - An error status otherwise
*/
QStatus GetElement(const char* elemSig, ...) const;
/**
* Equality operator.
*
* @param other The other MsgArg to compare.
*
* @return Returns true if the two message args have the same signatures and values.
*/
bool operator==(const MsgArg& other);
/**
* Inequality operator.
*
* @param other The other MsgArg to compare.
*
* @return Returns true if the two message args do not have the same signatures and values.
*/
bool operator!=(const MsgArg& other) { return !(*this == other); }
/**
* Clear the MsgArg setting the type to ALLJOYN_INVALID and freeing any memory allocated for the
* MsgArg value.
*/
void Clear();
/**
* Makes a MsgArg stable by completely copying the contents into locally
* managed memory. After a MsgArg has been stabilized any values used to
* initialize or set the message arg can be freed.
*/
void Stabilize();
/**
* This method sets the ownership flags on this MsgArg, and optionally all
* MsgArgs subordinate to this MsgArg. By setting the ownership flags the
* caller can transfer responsibility for freeing nested data referenced
* by this MsgArg to the MsgArg's destructor. The #OwnsArgs flag is
* particularly useful for managing complex data structures such as arrays
* of structs, nested structs, and variants where the inner MsgArgs are
* dynamically allocated. The #OwnsData flag is useful for freeing
* dynamically allocated strings, byte arrays, etc,.
*
* @param ownershipFlags A logical or of the applicable ownership flags (OwnsArgs and OwnsData).
* @param deep If true recursively sets the ownership flags on all MsgArgs owned by this MsgArg.
*/
void SetOwnershipFlags(uint8_t ownershipFlags, bool deep = false) { this->flags |= (ownershipFlags & (OwnsData | OwnsArgs)); if (deep) { SetOwnershipDeep(); } }
/**
* Default constructor - arg instances start out invalid
*/
MsgArg() : typeId(ALLJOYN_INVALID), flags(0) { v_invalid.unused[0] = v_invalid.unused[1] = v_invalid.unused[2] = NULL; }
protected:
/**
* Build up a MsgArg from a variable set of parameters.
*
* @param signature The signature for MsgArg values
* @param sigLen Length of the specified signature
* @param arg MsgArg to initialize
* @param maxArgs Maximum number of arguments to parse in parameter list, argp
* @param argp List of parameters constructed from var args
* @param count Out parameter that contains the number of actual parsed var args
*
* @return
* - #ER_OK if the MsgArg was successfully created.
* - #ER_BUS_SIGNATURE_MISMATCH if the signature did not match.
* - Other error status codes indicating a failure.
*/
static QStatus VBuildArgs(const char*& signature, size_t sigLen, MsgArg* arg, size_t maxArgs, va_list* argp, size_t* count = NULL);
/**
* Parse a MsgArg into a variable set of receiving parameters.
*
* @param signature The signature for MsgArg values
* @param sigLen Length of the specified signature
* @param argList MsgArg to parse
* @param numArgs Maximum number of arguments to parse in parameter list, argp
* @param argp List of parameters to receive values constructed from var args
*
* @return
* - #ER_OK if the MsgArg was successfully parsed.
* - #ER_BUS_SIGNATURE_MISMATCH if the signature did not match.
* - Other error status codes indicating a failure.
*/
static QStatus VParseArgs(const char*& signature, size_t sigLen, const MsgArg* argList, size_t numArgs, va_list* argp);
private:
/**
* flags indicating owner ship
*
* @see OwnsData
* @see OwnsArg
*/
uint8_t flags;
/**
* Recursively sets the ownership flags on the entire MsgArg tree.
* @see SetOwnershipFlags
*/
void SetOwnershipDeep();
/**
* Clone one MsgArg into Another MsgArg
*
* On 32bit Windows the export convention for Scons and Visual Studio builds is __stdcall
* while for Visual Studio alone is __cdecl. This requires the explicit __stdcall (via
* the AJ_CALL macro) applied to the public C++ API methods. This method is not public,
* but it is invoked from two public methods which are inline (the copy constructor
* and the assignment operator of this class) thus it also needs the decoration.
*
* @see operator=
* @see MsgArg(const MsgArg&)
*
* @param dest the MsgArg that will hold the clone
* @param src the MsgArg that will be cloned
*
*/
static void AJ_CALL Clone(MsgArg& dest, const MsgArg& src);
/**
* Used to help build an alljoyn array
*
* AllJoyn arrays are any MsgArgs with the letter `a` in the signature
*
* Note that `arry` is not a typo - Some editors tag `array` as a reserved word.
*
* @param arry the MsgArg that will hold the array
* @param elemSig The signature for MsgArg array element
* @param argp List of parameters to receive values constructed from var args
*
* @see Set
* @see VBuildArgs
*
*
* @return
* - #ER_OK if the MsgArg was successfully created.
* - #ER_BUS_BAD_SIGNATURE invalid value in the array signature
* - #ER_BUS_BAD_VALUE array element does not have an expected value
* - Other error status codes indicating a failure.
*/
static QStatus BuildArray(MsgArg* arry, const qcc::String& elemSig, va_list* argp);
/**
* Used to help parse an alljoyn array
*
* AllJoyn arrays are any MsgArgs with the letter `a` in the signature
*
* Note that `arry` is not a typo - Some editors tag `array` as a reserved word.
*
* @see Get
* @see VParseArgs
*
* @param arry the MsgArg that will hold the array
* @param elemSig The signature for MsgArg array element
* @param elemSigLen Length of the array element signature
* @param argp List of parameters to receive values constructed from var args
*
* @return
* - #ER_OK if the MsgArg was successfully created.
* - #ER_BUS_BAD_SIGNATURE invalid value in the array signature
* - #ER_BUS_BAD_VALUE array element does not have an expected value
* - #ER_INVALID_ADDRESS the argp value is invalid
* - Other error status codes indicating a failure
*/
static QStatus ParseArray(const MsgArg* arry, const char* elemSig, size_t elemSigLen, va_list* argp);
};
}
#endif
|