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