1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 #ifndef ICEPHP_TYPES_H 6 #define ICEPHP_TYPES_H 7 8 #include <Config.h> 9 #include <Communicator.h> 10 #include <Operation.h> 11 #include <IceUtil/OutputUtil.h> 12 13 // 14 // Global functions. 15 // 16 extern "C" 17 { 18 ZEND_FUNCTION(IcePHP_defineEnum); 19 ZEND_FUNCTION(IcePHP_defineStruct); 20 ZEND_FUNCTION(IcePHP_defineSequence); 21 ZEND_FUNCTION(IcePHP_defineDictionary); 22 ZEND_FUNCTION(IcePHP_declareProxy); 23 ZEND_FUNCTION(IcePHP_defineProxy); 24 ZEND_FUNCTION(IcePHP_declareClass); 25 ZEND_FUNCTION(IcePHP_defineClass); 26 ZEND_FUNCTION(IcePHP_defineException); 27 ZEND_FUNCTION(IcePHP_stringify); 28 ZEND_FUNCTION(IcePHP_stringifyException); 29 } 30 31 namespace IcePHP 32 { 33 34 // 35 // This class is raised as an exception when object marshaling needs to be aborted. 36 // 37 class AbortMarshaling 38 { 39 }; 40 41 class ClassInfo; 42 typedef IceUtil::Handle<ClassInfo> ClassInfoPtr; 43 typedef std::vector<ClassInfoPtr> ClassInfoList; 44 45 typedef std::map<unsigned int, Ice::ObjectPtr> ObjectMap; 46 47 class ObjectReader; 48 typedef IceUtil::Handle<ObjectReader> ObjectReaderPtr; 49 50 struct PrintObjectHistory 51 { 52 int index; 53 std::map<unsigned int, int> objects; 54 }; 55 56 // 57 // The delayed nature of class unmarshaling in the Ice protocol requires us to 58 // handle unmarshaling using a callback strategy. An instance of UnmarshalCallback 59 // is supplied to each type's unmarshal() member function. For all types except 60 // classes, the callback is invoked with the unmarshaled value before unmarshal() 61 // returns. For class instances, however, the callback may not be invoked until 62 // the stream's finished() function is called. 63 // 64 class UnmarshalCallback : public IceUtil::Shared 65 { 66 public: 67 68 virtual ~UnmarshalCallback(); 69 70 // 71 // The unmarshaled() member function receives the unmarshaled value. The 72 // last two arguments are the values passed to unmarshal() for use by 73 // UnmarshalCallback implementations. 74 // 75 virtual void unmarshaled(zval*, zval*, void*) = 0; 76 }; 77 typedef IceUtil::Handle<UnmarshalCallback> UnmarshalCallbackPtr; 78 79 // 80 // ReadObjectCallback retains all of the information necessary to store an unmarshaled 81 // Slice value as a PHP object. 82 // 83 class ReadObjectCallback : public IceUtil::Shared 84 { 85 public: 86 87 ReadObjectCallback(const ClassInfoPtr&, const UnmarshalCallbackPtr&, zval*, void*); 88 ~ReadObjectCallback(); 89 90 virtual void invoke(const ::Ice::ObjectPtr&); 91 92 private: 93 94 ClassInfoPtr _info; 95 UnmarshalCallbackPtr _cb; 96 zval _target; 97 void* _closure; 98 }; 99 typedef IceUtil::Handle<ReadObjectCallback> ReadObjectCallbackPtr; 100 101 // 102 // This class keeps track of PHP objects (instances of Slice classes 103 // and exceptions) that have preserved slices. 104 // 105 class StreamUtil 106 { 107 public: 108 109 ~StreamUtil(); 110 111 // 112 // Keep a reference to a ReadObjectCallback for patching purposes. 113 // 114 void add(const ReadObjectCallbackPtr&); 115 116 // 117 // Keep track of object instances that have preserved slices. 118 // 119 void add(const ObjectReaderPtr&); 120 121 void updateSlicedData(void); 122 123 static void setSlicedDataMember(zval*, const Ice::SlicedDataPtr&); 124 static Ice::SlicedDataPtr getSlicedDataMember(zval*, ObjectMap*); 125 126 private: 127 128 std::vector<ReadObjectCallbackPtr> _callbacks; 129 std::set<ObjectReaderPtr> _readers; 130 static zend_class_entry* _slicedDataType; 131 static zend_class_entry* _sliceInfoType; 132 }; 133 134 // 135 // Base class for type information. 136 // 137 class TypeInfo : public UnmarshalCallback 138 { 139 public: 140 141 virtual std::string getId() const = 0; 142 143 virtual bool validate(zval*, bool) = 0; // Validate type data. Bool enables excpetion throwing. 144 145 virtual bool variableLength() const = 0; 146 virtual int wireSize() const = 0; 147 virtual Ice::OptionalFormat optionalFormat() const = 0; 148 149 virtual bool usesClasses() const; // Default implementation returns false. 150 151 virtual void unmarshaled(zval*, zval*, void*); // Default implementation is assert(false). 152 153 virtual void destroy(); 154 155 protected: 156 157 TypeInfo(); 158 159 public: 160 161 // 162 // The marshal and unmarshal functions can raise Ice exceptions, and may raise 163 // AbortMarshaling if an error occurs. 164 // 165 virtual void marshal(zval*, Ice::OutputStream*, ObjectMap*, bool) = 0; 166 virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, 167 zval*, void*, bool) = 0; 168 169 virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*) = 0; 170 }; 171 typedef IceUtil::Handle<TypeInfo> TypeInfoPtr; 172 173 // 174 // Primitive type information. 175 // 176 class PrimitiveInfo : public TypeInfo 177 { 178 public: 179 180 virtual std::string getId() const; 181 182 virtual bool validate(zval*, bool); 183 184 virtual bool variableLength() const; 185 virtual int wireSize() const; 186 virtual Ice::OptionalFormat optionalFormat() const; 187 188 virtual void marshal(zval*, Ice::OutputStream*, ObjectMap*, bool); 189 virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, 190 zval*, void*, bool); 191 192 virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 193 194 enum Kind 195 { 196 KindBool, 197 KindByte, 198 KindShort, 199 KindInt, 200 KindLong, 201 KindFloat, 202 KindDouble, 203 KindString 204 }; 205 206 Kind kind; 207 }; 208 typedef IceUtil::Handle<PrimitiveInfo> PrimitiveInfoPtr; 209 210 // 211 // Enum information. 212 // 213 class EnumInfo : public TypeInfo 214 { 215 public: 216 217 EnumInfo(const std::string&, zval*); 218 219 virtual std::string getId() const; 220 221 virtual bool validate(zval*, bool); 222 223 virtual bool variableLength() const; 224 virtual int wireSize() const; 225 virtual Ice::OptionalFormat optionalFormat() const; 226 227 virtual void marshal(zval*, Ice::OutputStream*, ObjectMap*, bool); 228 virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, 229 zval*, void*, bool); 230 231 virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 232 233 const std::string id; 234 const std::map<Ice::Int, std::string> enumerators; 235 const Ice::Int maxValue; 236 237 }; 238 typedef IceUtil::Handle<EnumInfo> EnumInfoPtr; 239 240 class DataMember : public UnmarshalCallback 241 { 242 public: 243 244 virtual void unmarshaled(zval*, zval*, void*); 245 246 void setMember(zval*, zval*); 247 248 std::string name; 249 TypeInfoPtr type; 250 bool optional; 251 int tag; 252 }; 253 typedef IceUtil::Handle<DataMember> DataMemberPtr; 254 typedef std::vector<DataMemberPtr> DataMemberList; 255 256 // 257 // Struct information. 258 // 259 class StructInfo : public TypeInfo 260 { 261 public: 262 263 StructInfo(const std::string&, const std::string&, zval*); 264 265 virtual std::string getId() const; 266 267 virtual bool validate(zval*, bool); 268 269 virtual bool variableLength() const; 270 virtual int wireSize() const; 271 virtual Ice::OptionalFormat optionalFormat() const; 272 273 virtual bool usesClasses() const; 274 275 virtual void marshal(zval*, Ice::OutputStream*, ObjectMap*, bool); 276 virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, 277 zval*, void*, bool); 278 279 virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 280 281 virtual void destroy(); 282 283 const std::string id; 284 const std::string name; // PHP class name 285 const DataMemberList members; 286 const zend_class_entry* zce; 287 288 private: 289 290 bool _variableLength; 291 int _wireSize; 292 zval _nullMarshalValue; 293 }; 294 typedef IceUtil::Handle<StructInfo> StructInfoPtr; 295 296 // 297 // Sequence information. 298 // 299 class SequenceInfo : public TypeInfo 300 { 301 public: 302 303 SequenceInfo(const std::string&, zval*); 304 305 virtual std::string getId() const; 306 307 virtual bool validate(zval*, bool); 308 309 virtual bool variableLength() const; 310 virtual int wireSize() const; 311 virtual Ice::OptionalFormat optionalFormat() const; 312 313 virtual bool usesClasses() const; 314 315 virtual void marshal(zval*, Ice::OutputStream*, ObjectMap*, bool); 316 virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, 317 zval*, void*, bool); 318 319 virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 320 321 virtual void unmarshaled(zval*, zval*, void*); 322 323 virtual void destroy(); 324 325 const std::string id; 326 const TypeInfoPtr elementType; 327 328 private: 329 330 void marshalPrimitiveSequence(const PrimitiveInfoPtr&, zval*, Ice::OutputStream*); 331 void unmarshalPrimitiveSequence(const PrimitiveInfoPtr&, Ice::InputStream*, const UnmarshalCallbackPtr&, 332 zval*, void*); 333 }; 334 typedef IceUtil::Handle<SequenceInfo> SequenceInfoPtr; 335 336 // 337 // Dictionary information. 338 // 339 class DictionaryInfo : public TypeInfo 340 { 341 public: 342 343 DictionaryInfo(const std::string&, zval*, zval*); 344 345 virtual std::string getId() const; 346 347 virtual bool validate(zval*, bool); 348 349 virtual bool variableLength() const; 350 virtual int wireSize() const; 351 virtual Ice::OptionalFormat optionalFormat() const; 352 353 virtual bool usesClasses() const; 354 355 virtual void marshal(zval*, Ice::OutputStream*, ObjectMap*, bool); 356 virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, 357 zval*, void*, bool); 358 359 virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 360 361 virtual void destroy(); 362 363 class KeyCallback : public UnmarshalCallback 364 { 365 public: 366 367 KeyCallback(); 368 ~KeyCallback(); 369 370 virtual void unmarshaled(zval*, zval*, void*); 371 372 zval key; 373 }; 374 typedef IceUtil::Handle<KeyCallback> KeyCallbackPtr; 375 376 class ValueCallback : public UnmarshalCallback 377 { 378 public: 379 380 ValueCallback(zval*); 381 ~ValueCallback(); 382 383 virtual void unmarshaled(zval*, zval*, void*); 384 385 zval key; 386 }; 387 typedef IceUtil::Handle<ValueCallback> ValueCallbackPtr; 388 389 std::string id; 390 TypeInfoPtr keyType; 391 TypeInfoPtr valueType; 392 393 private: 394 395 bool _variableLength; 396 int _wireSize; 397 }; 398 typedef IceUtil::Handle<DictionaryInfo> DictionaryInfoPtr; 399 400 class ExceptionInfo; 401 typedef IceUtil::Handle<ExceptionInfo> ExceptionInfoPtr; 402 typedef std::vector<ExceptionInfoPtr> ExceptionInfoList; 403 404 typedef std::vector<TypeInfoPtr> TypeInfoList; 405 406 class ClassInfo : public TypeInfo 407 { 408 public: 409 410 ClassInfo(const std::string&); 411 412 void define(const std::string&, Ice::Int, bool, bool, zval*, zval*); 413 414 virtual std::string getId() const; 415 416 virtual bool validate(zval*, bool); 417 418 virtual bool variableLength() const; 419 virtual int wireSize() const; 420 virtual Ice::OptionalFormat optionalFormat() const; 421 422 virtual bool usesClasses() const; 423 424 virtual void marshal(zval*, Ice::OutputStream*, ObjectMap*, bool); 425 virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, 426 zval*, void*, bool); 427 428 virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 429 430 virtual void destroy(); 431 432 void printMembers(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 433 434 bool isA(const std::string&) const; 435 436 const std::string id; 437 const std::string name; // PHP class name 438 const Ice::Int compactId; 439 const bool preserve; 440 const bool interface; 441 const ClassInfoPtr base; 442 const DataMemberList members; 443 const DataMemberList optionalMembers; 444 const zend_class_entry* zce; 445 bool defined; 446 }; 447 448 // 449 // Proxy information. 450 // 451 452 class ProxyInfo; 453 typedef IceUtil::Handle<ProxyInfo> ProxyInfoPtr; 454 typedef std::vector<ProxyInfoPtr> ProxyInfoList; 455 456 class ProxyInfo : public TypeInfo 457 { 458 public: 459 460 ProxyInfo(const std::string&); 461 462 void define(zval*, zval*); 463 464 virtual std::string getId() const; 465 466 virtual bool validate(zval*, bool); 467 468 virtual bool variableLength() const; 469 virtual int wireSize() const; 470 virtual Ice::OptionalFormat optionalFormat() const; 471 472 virtual void marshal(zval*, Ice::OutputStream*, ObjectMap*, bool); 473 virtual void unmarshal(Ice::InputStream*, const UnmarshalCallbackPtr&, const CommunicatorInfoPtr&, 474 zval*, void*, bool); 475 476 virtual void print(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 477 478 virtual void destroy(); 479 bool isA(const std::string&) const; 480 481 void addOperation(const std::string&, const OperationPtr&); 482 OperationPtr getOperation(const std::string&) const; 483 484 const std::string id; 485 const ProxyInfoPtr base; 486 const ProxyInfoList interfaces; 487 bool defined; 488 typedef std::map<std::string, OperationPtr> OperationMap; 489 OperationMap operations; 490 }; 491 492 // 493 // Exception information. 494 // 495 class ExceptionInfo : public IceUtil::Shared 496 { 497 public: 498 499 zval* unmarshal(Ice::InputStream*, const CommunicatorInfoPtr&); 500 501 void print(zval*, IceUtilInternal::Output&); 502 void printMembers(zval*, IceUtilInternal::Output&, PrintObjectHistory*); 503 504 bool isA(const std::string&) const; 505 506 std::string id; 507 std::string name; // PHP class name 508 bool preserve; 509 ExceptionInfoPtr base; 510 DataMemberList members; 511 DataMemberList optionalMembers; 512 bool usesClasses; 513 zend_class_entry* zce; 514 }; 515 516 ClassInfoPtr getClassInfoById(const std::string&); 517 ClassInfoPtr getClassInfoByName(const std::string&); 518 ProxyInfoPtr getProxyInfo(const std::string&); 519 ExceptionInfoPtr getExceptionInfo(const std::string&); 520 521 bool isUnset(zval*); 522 void assignUnset(zval*); 523 524 bool typesInit(INIT_FUNC_ARGS); 525 bool typesRequestInit(void); 526 bool typesRequestShutdown(void); 527 528 // 529 // ObjectWriter wraps a PHP object for marshaling. 530 // 531 class ObjectWriter : public Ice::Object 532 { 533 public: 534 535 ObjectWriter(zval*, ObjectMap*, const ClassInfoPtr&); 536 ~ObjectWriter(); 537 538 virtual void ice_preMarshal(); 539 540 virtual void _iceWrite(Ice::OutputStream*) const; 541 virtual void _iceRead(Ice::InputStream*); 542 543 private: 544 545 void writeMembers(Ice::OutputStream*, const DataMemberList&) const; 546 547 zval _object; 548 ObjectMap* _map; 549 ClassInfoPtr _info; 550 ClassInfoPtr _formal; 551 }; 552 553 // 554 // ObjectReader unmarshals the state of an Ice object. 555 // 556 class ObjectReader : public Ice::Object 557 { 558 public: 559 560 ObjectReader(zval*, const ClassInfoPtr&, const CommunicatorInfoPtr&); 561 ~ObjectReader(); 562 563 virtual void ice_postUnmarshal(); 564 565 virtual void _iceWrite(Ice::OutputStream*) const; 566 virtual void _iceRead(Ice::InputStream*); 567 568 virtual ClassInfoPtr getInfo() const; 569 570 zval* getObject() const; 571 572 Ice::SlicedDataPtr getSlicedData() const; 573 574 private: 575 576 zval _object; 577 ClassInfoPtr _info; 578 CommunicatorInfoPtr _communicator; 579 Ice::SlicedDataPtr _slicedData; 580 }; 581 582 // 583 // ExceptionReader creates a PHP user exception and unmarshals it. 584 // 585 class ExceptionReader : public Ice::UserException 586 { 587 public: 588 589 ExceptionReader(const CommunicatorInfoPtr&, const ExceptionInfoPtr&); 590 ~ExceptionReader() throw(); 591 592 virtual std::string ice_id() const; 593 virtual ExceptionReader* ice_clone() const; 594 virtual void ice_throw() const; 595 596 virtual void _write(Ice::OutputStream*) const; 597 virtual void _read(Ice::InputStream*); 598 virtual bool _usesClasses() const; 599 600 ExceptionInfoPtr getInfo() const; 601 602 zval* getException() const; 603 604 Ice::SlicedDataPtr getSlicedData() const; 605 606 protected: 607 _writeImpl(Ice::OutputStream *)608 virtual void _writeImpl(Ice::OutputStream*) const {} _readImpl(Ice::InputStream *)609 virtual void _readImpl(Ice::InputStream*) {} 610 611 private: 612 613 CommunicatorInfoPtr _communicatorInfo; 614 ExceptionInfoPtr _info; 615 zval* _ex; 616 Ice::SlicedDataPtr _slicedData; 617 }; 618 619 class IdResolver : public Ice::CompactIdResolver 620 { 621 public: 622 623 IdResolver(void); 624 virtual std::string resolve(Ice::Int) const; 625 }; 626 627 } // End of namespace IcePHP 628 629 #endif 630