- Timestamp:
- Aug 28, 2018 8:57:23 PM (6 years ago)
- Location:
- trunk
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/include/iprt/cpp/restbase.h
r73930 r73933 295 295 kCollectionFormat_ssv, /**< Space-separated list. */ 296 296 kCollectionFormat_tsv, /**< Tab-separated list. */ 297 kCollectionFormat_pipes /**< Pipe-separated list. */ 297 kCollectionFormat_pipes, /**< Pipe-separated list. */ 298 kCollectionFormat_Mask = 7 /**< Collection type mask. */ 298 299 }; 299 300 … … 328 329 */ 329 330 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, 330 331 uint32_t a_fFlags = kCollectionFormat_Unspecified); 331 332 332 333 /** … … 334 335 */ 335 336 virtual const char *getType(void) = 0; 337 338 /** 339 * Factory method. 340 * @returns Pointer to new object on success, NULL if out of memory. 341 */ 342 typedef DECLCALLBACK(RTCRestObjectBase *) FNCREATEINSTANCE(void); 343 /** Pointer to factory method. */ 344 typedef FNCREATEINSTANCE *PFNCREATEINSTANCE; 336 345 }; 337 346 … … 363 372 virtual const char *getType(void) RT_OVERRIDE; 364 373 374 /** Factory method. */ 375 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void); 376 365 377 public: 366 378 /** The value. */ … … 395 407 virtual const char *getType(void) RT_OVERRIDE; 396 408 409 /** Factory method. */ 410 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void); 411 397 412 public: 398 413 /** The value. */ … … 427 442 virtual const char *getType(void) RT_OVERRIDE; 428 443 444 /** Factory method. */ 445 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void); 446 429 447 public: 430 448 /** The value. */ … … 459 477 virtual const char *getType(void) RT_OVERRIDE; 460 478 479 /** Factory method. */ 480 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void); 481 461 482 public: 462 483 /** The value. */ … … 491 512 virtual const char *getType(void) RT_OVERRIDE; 492 513 514 /** Factory method. */ 515 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void); 516 493 517 public: 494 518 /** The value. */ … … 522 546 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE; 523 547 virtual const char *getType(void) RT_OVERRIDE; 548 549 /** Factory method. */ 550 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void); 524 551 }; 525 552 … … 528 555 * Limited array class. 529 556 */ 530 template<class Type> class RTCRestArray : public RTCRestObjectBase557 template<class ElementType> class RTCRestArray : public RTCRestObjectBase 531 558 { 532 559 public: … … 535 562 /** @todo more later. */ 536 563 537 virtual void resetToDefault() RT_OVERRIDE; 538 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE; 564 virtual void resetToDefault() RT_OVERRIDE 565 { 566 } 567 568 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE 569 { 570 RT_NOREF(a_rDst); 571 return a_rDst; 572 } 573 539 574 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE 540 575 { … … 542 577 return VERR_NOT_IMPLEMENTED; 543 578 } 579 544 580 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, 545 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE; 546 virtual const char *getType(void) RT_OVERRIDE; 581 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE 582 { 583 RT_NOREF(a_rValue, a_pszName, a_pErrInfo, a_fFlags); 584 return VERR_NOT_IMPLEMENTED; 585 } 586 587 virtual const char *getType(void) RT_OVERRIDE 588 { 589 return "RTCRestArray<ElementType>"; 590 } 591 592 /** Factory method. */ 593 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) 594 { 595 return new RTCRestArray<ElementType>(); 596 } 597 598 /** Factory method for elements. */ 599 static DECLCALLBACK(RTCRestObjectBase *) createElementInstance(void) 600 { 601 return new ElementType(); 602 } 547 603 }; 548 604 … … 551 607 * Limited map class. 552 608 */ 553 template<class Type> class RTCRestStringMap : public RTCRestObjectBase609 template<class ElementType> class RTCRestStringMap : public RTCRestObjectBase 554 610 { 555 611 public: … … 558 614 /** @todo more later. */ 559 615 560 virtual void resetToDefault() RT_OVERRIDE; 561 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE; 616 virtual void resetToDefault() RT_OVERRIDE 617 { 618 } 619 620 virtual RTCRestOutputBase &serializeAsJson(RTCRestOutputBase &a_rDst) const RT_OVERRIDE 621 { 622 RT_NOREF(a_rDst); 623 return a_rDst; 624 } 625 562 626 virtual int deserializeFromJson(RTCRestJsonCursor const &a_rCursor) RT_OVERRIDE 563 627 { … … 565 629 return VERR_NOT_IMPLEMENTED; 566 630 } 631 567 632 virtual int fromString(RTCString const &a_rValue, const char *a_pszName, PRTERRINFO a_pErrInfo = NULL, 568 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE; 569 virtual const char *getType(void) RT_OVERRIDE; 633 uint32_t a_fFlags = kCollectionFormat_Unspecified) RT_OVERRIDE 634 { 635 RT_NOREF(a_rValue, a_pszName, a_pErrInfo, a_fFlags); 636 return VERR_NOT_IMPLEMENTED; 637 } 638 639 virtual const char *getType(void) RT_OVERRIDE 640 { 641 return "RTCRestStringMap<ElementType>"; 642 } 643 644 /** Factory method. */ 645 static DECLCALLBACK(RTCRestObjectBase *) createInstance(void) 646 { 647 return new RTCRestStringMap<ElementType>(); 648 } 649 650 /** Factory method for elements. */ 651 static DECLCALLBACK(RTCRestObjectBase *) createElementInstance(void) 652 { 653 return new ElementType(); 654 } 570 655 }; 571 656 … … 743 828 * @param ... Message arguments. 744 829 */ 745 int addError(int a_rc, const char *a_pszFormat, ...); 830 int addError(int a_rc, const char *a_pszFormat, ...); 831 832 /** Field flags. */ 833 enum 834 { 835 /** Collection map, name is a prefix followed by '*'. */ 836 kHdrField_MapCollection = RT_BIT_32(24), 837 /** Array collection, i.e. the heade field may appear more than once. */ 838 kHdrField_ArrayCollection = RT_BIT_32(25), 839 }; 840 841 /** Header field descriptor. */ 842 typedef struct 843 { 844 /** The header field name. */ 845 const char *pszName; 846 /** The length of the field name.*/ 847 uint32_t cchName; 848 /** Flags, TBD. */ 849 uint32_t fFlags; 850 /** Object factory. */ 851 RTCRestObjectBase::PFNCREATEINSTANCE pfnCreateInstance; 852 } HEADERFIELDDESC; 853 854 /** 855 * Helper that extracts fields from the HTTP headers. 856 * 857 * @param a_paFieldsDesc Pointer to an array of field descriptors. 858 * @param a_pappFieldValues Pointer to a parallel array of value pointer pointers. 859 * @param a_cFields Number of field descriptors.. 860 * @param a_pchData The header blob to search. 861 * @param a_cbData The size of the header blob to search. 862 */ 863 void extracHeaderFieldsFromBlob(HEADERFIELDDESC const *a_paFieldDescs, RTCRestObjectBase ***a_pappFieldValues, 864 size_t a_cFields, const char *a_pchData, size_t a_cbData); 746 865 747 866 /** -
trunk/include/iprt/err.h
r73930 r73933 3214 3214 /** Server response contains embedded zero character(s). */ 3215 3215 #define VERR_REST_RESPONSE_EMBEDDED_ZERO_CHAR (-25702) 3216 /** Server response contains unexpected repetitive header field. */ 3217 #define VERR_REST_RESPONSE_REPEAT_HEADER_FIELD (-25703) 3216 3218 /** @} */ 3217 3219 -
trunk/src/VBox/Runtime/common/rest/RTCRestClientResponseBase.cpp
r73930 r73933 180 180 } 181 181 182 183 void RTCRestClientResponseBase::extracHeaderFieldsFromBlob(HEADERFIELDDESC const *a_paFieldDescs, 184 RTCRestObjectBase ***a_pappFieldValues, 185 size_t a_cFields, const char *a_pchData, size_t a_cbData) 186 187 { 188 RTCString strValue; /* (Keep it out here to encourage buffer allocation reuse and default construction call.) */ 189 190 /* 191 * Work our way through the header blob. 192 */ 193 while (a_cbData >= 2) 194 { 195 /* 196 * Determine length of the header name:value combo. 197 * Note! Multi-line field values are not currently supported. 198 */ 199 const char *pchEol = (const char *)memchr(a_pchData, '\n', a_cbData); 200 while (pchEol && (pchEol == a_pchData || pchEol[-1] != '\r')) 201 pchEol = (const char *)memchr(pchEol, '\n', a_cbData - (pchEol - a_pchData)); 202 203 size_t const cchField = pchEol ? pchEol - a_pchData + 1 : a_cbData; 204 size_t const cchFieldNoCrLf = pchEol ? pchEol - a_pchData - 1 : a_cbData; 205 206 const char *pchColon = (const char *)memchr(a_pchData, ':', cchFieldNoCrLf); 207 Assert(pchColon); 208 if (pchColon) 209 { 210 size_t const cchName = pchColon - a_pchData; 211 size_t const offValue = cchName + (RT_C_IS_BLANK(pchColon[1]) ? 2 : 1); 212 size_t const cchValue = cchFieldNoCrLf - offValue; 213 214 /* 215 * Match headers. 216 */ 217 bool fHaveValue = false; 218 for (size_t i = 0; i < a_cFields; i++) 219 { 220 size_t const cchThisName = a_paFieldDescs[i].cchName; 221 if ( !(a_paFieldDescs[i].fFlags & kHdrField_MapCollection) 222 ? cchThisName == cchName 223 && RTStrNICmpAscii(a_pchData, a_paFieldDescs[i].pszName, cchThisName) == 0 224 : cchThisName <= cchName 225 && RTStrNICmpAscii(a_pchData, a_paFieldDescs[i].pszName, cchThisName - 1) == 0) 226 { 227 /* Get and clean the value. */ 228 int rc = VINF_SUCCESS; 229 if (!fHaveValue) 230 { 231 rc = strValue.assignNoThrow(&a_pchData[offValue], cchValue); 232 if (RT_SUCCESS(rc)) 233 { 234 RTStrPurgeEncoding(strValue.mutableRaw()); /** @todo this is probably a little wrong... */ 235 fHaveValue = true; 236 } 237 else 238 { 239 addError(rc, "Error allocating %u bytes for header field %s", a_paFieldDescs[i].pszName); 240 break; 241 } 242 } 243 244 /* 245 * Create field to deserialize. 246 */ 247 RTCRestObjectBase *pObj = NULL; 248 if (!(a_paFieldDescs[i].fFlags & (kHdrField_MapCollection | kHdrField_ArrayCollection))) 249 { 250 /* Only once. */ 251 if (!*a_pappFieldValues[i]) 252 { 253 pObj = a_paFieldDescs[i].pfnCreateInstance(); 254 if (pObj) 255 *a_pappFieldValues[i] = pObj; 256 else 257 { 258 addError(VERR_NO_MEMORY, "out of memory"); 259 continue; 260 } 261 } 262 else 263 { 264 addError(VERR_REST_RESPONSE_REPEAT_HEADER_FIELD, "Already saw header field '%s'", a_paFieldDescs[i].pszName); 265 continue; 266 } 267 } 268 else 269 { 270 Assert(a_paFieldDescs[i].pszName[cchThisName - 1] == '*'); 271 AssertMsgFailed(("impl field collections")); 272 continue; 273 } 274 275 /* 276 * Deserialize it. 277 */ 278 RTERRINFOSTATIC ErrInfo; 279 rc = pObj->fromString(strValue, a_paFieldDescs[i].pszName, RTErrInfoInitStatic(&ErrInfo), 280 a_paFieldDescs[i].fFlags & RTCRestObjectBase::kCollectionFormat_Mask); 281 if (RT_SUCCESS(rc)) 282 { /* likely */ } 283 else if (RTErrInfoIsSet(&ErrInfo.Core)) 284 addError(rc, "Error %Rrc parsing header field '%s': %s", 285 rc, a_paFieldDescs[i].pszName, ErrInfo.Core.pszMsg); 286 else 287 addError(rc, "Error %Rrc parsing header field '%s'", rc, a_paFieldDescs[i].pszName); 288 } 289 } 290 } 291 292 /* 293 * Advance to the next field. 294 */ 295 a_cbData -= cchField; 296 a_pchData += cchField; 297 } 298 } 182 299 183 300 int RTCRestClientResponseBase::extractHeaderFromBlob(const char *a_pszField, size_t a_cchField, -
trunk/src/VBox/Runtime/common/rest/rest-primary-object-types.cpp
r73920 r73933 101 101 *********************************************************************************************************************************/ 102 102 103 /** Factory method. */ 104 /*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestBool::createInstance(void) 105 { 106 return new (std::nothrow) RTCRestBool(); 107 } 108 109 103 110 /** Default destructor. */ 104 111 RTCRestBool::RTCRestBool() … … 206 213 207 214 215 208 216 /********************************************************************************************************************************* 209 217 * RTCRestInt64 implementation * 210 218 *********************************************************************************************************************************/ 219 220 /** Factory method. */ 221 /*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestInt64::createInstance(void) 222 { 223 return new (std::nothrow) RTCRestInt64(); 224 } 225 211 226 212 227 /** Default destructor. */ … … 312 327 * RTCRestInt32 implementation * 313 328 *********************************************************************************************************************************/ 329 330 /** Factory method. */ 331 /*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestInt32::createInstance(void) 332 { 333 return new (std::nothrow) RTCRestInt32(); 334 } 335 314 336 315 337 /** Default destructor. */ … … 422 444 *********************************************************************************************************************************/ 423 445 446 /** Factory method. */ 447 /*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestInt16::createInstance(void) 448 { 449 return new (std::nothrow) RTCRestInt16(); 450 } 451 452 424 453 /** Default destructor. */ 425 454 RTCRestInt16::RTCRestInt16() … … 531 560 *********************************************************************************************************************************/ 532 561 562 /** Factory method. */ 563 /*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestDouble::createInstance(void) 564 { 565 return new (std::nothrow) RTCRestDouble(); 566 } 567 533 568 /** Default destructor. */ 534 569 RTCRestDouble::RTCRestDouble() … … 634 669 *********************************************************************************************************************************/ 635 670 671 /** Factory method. */ 672 /*static*/ DECLCALLBACK(RTCRestObjectBase *) RTCRestString::createInstance(void) 673 { 674 return new (std::nothrow) RTCRestString(); 675 } 676 677 636 678 /** Default destructor. */ 637 679 RTCRestString::RTCRestString()
Note:
See TracChangeset
for help on using the changeset viewer.