sebastian               Wed Feb  1 07:42:40 2006 UTC

  Modified files:              (Branch: PHP_5_0)
    /php-src/ext/com_dotnet     com_persist.c 
  Log:
  MFB: Fix line endings.
  
http://cvs.php.net/viewcvs.cgi/php-src/ext/com_dotnet/com_persist.c?r1=1.2&r2=1.2.2.1&diff_format=u
Index: php-src/ext/com_dotnet/com_persist.c
diff -u php-src/ext/com_dotnet/com_persist.c:1.2 
php-src/ext/com_dotnet/com_persist.c:1.2.2.1
--- php-src/ext/com_dotnet/com_persist.c:1.2    Wed Jun 16 23:57:25 2004
+++ php-src/ext/com_dotnet/com_persist.c        Wed Feb  1 07:42:40 2006
@@ -1,789 +1,789 @@
-/*
-   +----------------------------------------------------------------------+
-   | PHP Version 5                                                        |
-   +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2004 The PHP Group                                |
-   +----------------------------------------------------------------------+
-   | This source file is subject to version 3.0 of the PHP license,       |
-   | that is bundled with this package in the file LICENSE, and is        |
-   | available through the world-wide-web at the following url:           |
-   | http://www.php.net/license/3_0.txt.                                  |
-   | If you did not receive a copy of the PHP license and are unable to   |
-   | obtain it through the world-wide-web, please send a note to          |
-   | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
-   +----------------------------------------------------------------------+
-   | Author: Wez Furlong  <[EMAIL PROTECTED]>                          |
-   +----------------------------------------------------------------------+
- */
-
-/* $Id: com_persist.c,v 1.2 2004/06/16 23:57:25 abies Exp $ */
-
-/* Infrastructure for working with persistent COM objects.
- * Implements: IStream* wrapper for PHP streams.
- * TODO: Magic __wakeup and __sleep handlers for serialization 
- * (can wait till 5.1) */
-
-#ifdef HAVE_CONFIG_H
-#include "config.h"
-#endif
-
-#include "php.h"
-#include "php_ini.h"
-#include "ext/standard/info.h"
-#include "php_com_dotnet.h"
-#include "php_com_dotnet_internal.h"
-#include "Zend/zend_exceptions.h"
-
-/* {{{ expose php_stream as a COM IStream */
-
-typedef struct {
-       CONST_VTBL struct IStreamVtbl *lpVtbl;
-       THREAD_T engine_thread;
-       LONG refcount;
-       php_stream *stream;
-       int id;
-} php_istream;
-
-static int le_istream;
-static void istream_destructor(php_istream *stm);
-
-static void istream_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
-{
-       php_istream *stm = (php_istream *)rsrc->ptr;
-       istream_destructor(stm);
-}
-
-#define FETCH_STM()    \
-       php_istream *stm = (php_istream*)This; \
-       if (tsrm_thread_id() != stm->engine_thread) \
-               return E_UNEXPECTED;
-
-static HRESULT STDMETHODCALLTYPE stm_queryinterface(
-       IStream *This,
-       /* [in] */ REFIID riid,
-       /* [iid_is][out] */ void **ppvObject)
-{
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       if (IsEqualGUID(&IID_IUnknown, riid) ||
-                       IsEqualGUID(&IID_IStream, riid)) {
-               *ppvObject = This;
-               InterlockedIncrement(&stm->refcount);
-               return S_OK;
-       }
-
-       *ppvObject = NULL;
-       return E_NOINTERFACE;
-}
-
-static ULONG STDMETHODCALLTYPE stm_addref(IStream *This)
-{
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       return InterlockedIncrement(&stm->refcount);
-}
-        
-static ULONG STDMETHODCALLTYPE stm_release(IStream *This)
-{
-       ULONG ret;
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       ret = InterlockedDecrement(&stm->refcount);
-       if (ret == 0) {
-               /* destroy it */
-               if (stm->id)
-                       zend_list_delete(stm->id);
-       }
-       return ret;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_read(IStream *This, void *pv, ULONG cb, 
ULONG *pcbRead)
-{
-       int nread;
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       nread = php_stream_read(stm->stream, pv, cb);
-
-       if (pcbRead) {
-               *pcbRead = nread > 0 ? nread : 0;
-       }
-       if (nread > 0) {
-               return S_OK;
-       }
-       return S_FALSE;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_write(IStream *This, void const *pv, 
ULONG cb, ULONG *pcbWritten)
-{
-       int nwrote;
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       nwrote = php_stream_write(stm->stream, pv, cb);
-
-       if (pcbWritten) {
-               *pcbWritten = nwrote > 0 ? nwrote : 0;
-       }
-       if (nwrote > 0) {
-               return S_OK;
-       }
-       return S_FALSE;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_seek(IStream *This, LARGE_INTEGER 
dlibMove,
-               DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
-{
-       off_t offset;
-       int whence;
-       int ret;
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       switch (dwOrigin) {
-               case STREAM_SEEK_SET:   whence = SEEK_SET;      break;
-               case STREAM_SEEK_CUR:   whence = SEEK_CUR;      break;
-               case STREAM_SEEK_END:   whence = SEEK_END;      break;
-               default:
-                       return STG_E_INVALIDFUNCTION;
-       }
-       
-       if (dlibMove.HighPart) {
-               /* we don't support 64-bit offsets */
-               return STG_E_INVALIDFUNCTION;
-       }
-       
-       offset = dlibMove.QuadPart;
-
-       ret = php_stream_seek(stm->stream, offset, whence);
-
-       if (plibNewPosition) {
-               plibNewPosition->QuadPart = (ULONGLONG)(ret >= 0 ? ret : 0);
-       }
-
-       return ret >= 0 ? S_OK : STG_E_INVALIDFUNCTION;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_set_size(IStream *This, ULARGE_INTEGER 
libNewSize)
-{
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       if (libNewSize.HighPart) {
-               return STG_E_INVALIDFUNCTION;
-       }
-       
-       if (php_stream_truncate_supported(stm->stream)) {
-               int ret = php_stream_truncate_set_size(stm->stream, 
(size_t)libNewSize.QuadPart);
-
-               if (ret == 0) {
-                       return S_OK;
-               }
-       }
-
-       return STG_E_INVALIDFUNCTION;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_copy_to(IStream *This, IStream *pstm, 
ULARGE_INTEGER cb,
-               ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
-{
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       return E_NOTIMPL;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_commit(IStream *This, DWORD 
grfCommitFlags)
-{
-       TSRMLS_FETCH();
-       FETCH_STM();
-
-       php_stream_flush(stm->stream);
-
-       return S_OK;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_revert(IStream *This)
-{
-       /* NOP */
-       return S_OK;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_lock_region(IStream *This,
-       ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD lockType)
-{
-       return STG_E_INVALIDFUNCTION;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_unlock_region(IStream *This,
-               ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD lockType)
-{
-       return STG_E_INVALIDFUNCTION;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_stat(IStream *This,
-               STATSTG *pstatstg, DWORD grfStatFlag)
-{
-       return STG_E_INVALIDFUNCTION;
-}
-
-static HRESULT STDMETHODCALLTYPE stm_clone(IStream *This, IStream **ppstm)
-{
-       return STG_E_INVALIDFUNCTION;
-}
-
-static struct IStreamVtbl php_istream_vtbl = {
-       stm_queryinterface,
-       stm_addref,
-       stm_release,
-       stm_read,
-       stm_write,
-       stm_seek,
-       stm_set_size,
-       stm_copy_to,
-       stm_commit,
-       stm_revert,
-       stm_lock_region,
-       stm_unlock_region,
-       stm_stat,
-       stm_clone
-};
-
-static void istream_destructor(php_istream *stm)
-{
-       TSRMLS_FETCH();
-
-       if (stm->id) {
-               int id = stm->id;
-               stm->id = 0;
-               zend_list_delete(id);
-               return;
-       }
-
-       if (stm->refcount > 0) {
-               CoDisconnectObject((IUnknown*)stm, 0);
-       }
-
-       zend_list_delete(stm->stream->rsrc_id);
-
-       CoTaskMemFree(stm);
-}
-/* }}} */
-
-PHPAPI IStream *php_com_wrapper_export_stream(php_stream *stream TSRMLS_DC)
-{
-       php_istream *stm = (php_istream*)CoTaskMemAlloc(sizeof(*stm));
-
-       if (stm == NULL)
-               return NULL;
-
-       memset(stm, 0, sizeof(*stm));
-       stm->engine_thread = tsrm_thread_id();
-       stm->lpVtbl = &php_istream_vtbl;
-       stm->refcount = 1;
-       stm->stream = stream;
-
-       zend_list_addref(stream->rsrc_id);
-       stm->id = zend_list_insert(stm, le_istream);
-
-       return (IStream*)stm;
-}
-
-#define CPH_ME(fname, arginfo) PHP_ME(com_persist, fname, arginfo, 
ZEND_ACC_PUBLIC)
-#define CPH_SME(fname, arginfo)        PHP_ME(com_persist, fname, arginfo, 
ZEND_ACC_ALLOW_STATIC|ZEND_ACC_PUBLIC)
-#define CPH_METHOD(fname)              static PHP_METHOD(com_persist, fname)
-       
-#define CPH_FETCH()                            php_com_persist_helper *helper 
= (php_com_persist_helper*)zend_object_store_get_object(getThis() TSRMLS_CC);
-
-#define CPH_NO_OBJ()                   if (helper->unk == NULL) { 
php_com_throw_exception(E_INVALIDARG, "No COM object is associated with this 
helper instance" TSRMLS_CC); return; }
-
-typedef struct {
-       zend_object                     std;
-       long codepage;
-       IUnknown                        *unk;
-       IPersistStream          *ips;
-       IPersistStreamInit      *ipsi;
-       IPersistFile            *ipf;
-} php_com_persist_helper;
-
-static zend_object_handlers helper_handlers;
-static zend_class_entry *helper_ce;
-
-static inline HRESULT get_persist_stream(php_com_persist_helper *helper)
-{
-       if (!helper->ips && helper->unk) {
-               return IUnknown_QueryInterface(helper->unk, 
&IID_IPersistStream, &helper->ips);
-       }
-       return helper->ips ? S_OK : E_NOTIMPL;
-}
-
-static inline HRESULT get_persist_stream_init(php_com_persist_helper *helper)
-{
-       if (!helper->ipsi && helper->unk) {
-               return IUnknown_QueryInterface(helper->unk, 
&IID_IPersistStreamInit, &helper->ipsi);
-       }
-       return helper->ipsi ? S_OK : E_NOTIMPL;
-}
-
-static inline HRESULT get_persist_file(php_com_persist_helper *helper)
-{
-       if (!helper->ipf && helper->unk) {
-               return IUnknown_QueryInterface(helper->unk, &IID_IPersistFile, 
&helper->ipf);
-       }
-       return helper->ipf ? S_OK : E_NOTIMPL;
-}
-
-
-/* {{{ proto string COMPersistHelper::GetCurFile()
-   Determines the filename into which an object will be saved, or false if 
none is set, via IPersistFile::GetCurFile */
-CPH_METHOD(GetCurFileName)
-{
-       HRESULT res;
-       OLECHAR *olename = NULL;
-       CPH_FETCH();
-
-       CPH_NO_OBJ();
-       
-       res = get_persist_file(helper);
-       if (helper->ipf) {
-               res = IPersistFile_GetCurFile(helper->ipf, &olename);
-
-               if (res == S_OK) {
-                       Z_TYPE_P(return_value) = IS_STRING;
-                       Z_STRVAL_P(return_value) = 
php_com_olestring_to_string(olename,
-                                  &Z_STRLEN_P(return_value), helper->codepage 
TSRMLS_CC);
-                       CoTaskMemFree(olename);
-                       return;
-               } else if (res == S_FALSE) {
-                       CoTaskMemFree(olename);
-                       RETURN_FALSE;
-               }
-               php_com_throw_exception(res, NULL TSRMLS_CC);
-       } else {
-               php_com_throw_exception(res, NULL TSRMLS_CC);
-       }
-}
-/* }}} */
-
-
-/* {{{ proto bool COMPersistHelper::SaveToFile(string filename [, bool 
remember])
-   Persist object data to file, via IPersistFile::Save */
-CPH_METHOD(SaveToFile)
-{
-       HRESULT res;
-       char *filename, *fullpath = NULL;
-       int filename_len;
-       zend_bool remember = TRUE;
-       OLECHAR *olefilename = NULL;
-       CPH_FETCH();
-       
-       CPH_NO_OBJ();
-
-       res = get_persist_file(helper);
-       if (helper->ipf) {
-               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
"s!|b",
-                                       &filename, &filename_len, &remember)) {
-                       php_com_throw_exception(E_INVALIDARG, "Invalid 
arguments" TSRMLS_CC);
-                       return;
-               }
-
-               if (filename) {
-                       fullpath = expand_filepath(filename, NULL TSRMLS_CC);
-       
-                       if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, 
CHECKUID_CHECK_FILE_AND_DIR))) {
-                               RETURN_FALSE;
-                       }
-
-                       if (php_check_open_basedir(fullpath TSRMLS_CC)) {
-                               RETURN_FALSE;
-                       }
-                       
-                       olefilename = php_com_string_to_olestring(filename, 
strlen(fullpath), helper->codepage TSRMLS_CC);
-                       efree(fullpath);
-               }
-               res = IPersistFile_Save(helper->ipf, olefilename, remember);
-               if (SUCCEEDED(res)) {
-                       if (!olefilename) {
-                               res = IPersistFile_GetCurFile(helper->ipf, 
&olefilename);
-                               if (S_OK == res) {
-                                       IPersistFile_SaveCompleted(helper->ipf, 
olefilename);
-                                       CoTaskMemFree(olefilename);
-                                       olefilename = NULL;
-                               }
-                       } else if (remember) {
-                               IPersistFile_SaveCompleted(helper->ipf, 
olefilename);
-                       }
-               }
-                       
-               if (olefilename) {
-                       efree(olefilename);
-               }
-
-               if (FAILED(res)) {
-                       php_com_throw_exception(res, NULL TSRMLS_CC);
-               }
-
-       } else {
-               php_com_throw_exception(res, NULL TSRMLS_CC);
-       }
-}
-/* }}} */
-
-/* {{{ proto bool COMPersistHelper::LoadFromFile(string filename [, int flags])
-   Load object data from file, via IPersistFile::Load */
-CPH_METHOD(LoadFromFile)
-{
-       HRESULT res;
-       char *filename, *fullpath;
-       int filename_len;
-       long flags = 0;
-       OLECHAR *olefilename;
-       CPH_FETCH();
-       
-       CPH_NO_OBJ();
-
-       res = get_persist_file(helper);
-       if (helper->ipf) {
-
-               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
"s|l",
-                                       &filename, &filename_len, &flags)) {
-                       php_com_throw_exception(E_INVALIDARG, "Invalid 
arguments" TSRMLS_CC);
-                       return;
-               }
-
-               fullpath = expand_filepath(filename, NULL TSRMLS_CC);
-
-               if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, 
CHECKUID_CHECK_FILE_AND_DIR))) {
-                       RETURN_FALSE;
-               }
-
-               if (php_check_open_basedir(fullpath TSRMLS_CC)) {
-                       RETURN_FALSE;
-               }
-
-               olefilename = php_com_string_to_olestring(fullpath, 
strlen(fullpath), helper->codepage TSRMLS_CC);
-               efree(fullpath);
-                       
-               res = IPersistFile_Load(helper->ipf, olefilename, flags);
-               efree(olefilename);
-
-               if (FAILED(res)) {
-                       php_com_throw_exception(res, NULL TSRMLS_CC);
-               }
-               
-       } else {
-               php_com_throw_exception(res, NULL TSRMLS_CC);
-       }
-}
-/* }}} */
-
-/* {{{ proto int COMPersistHelper::GetMaxStreamSize()
-   Gets maximum stream size required to store the object data, via 
IPersistStream::GetSizeMax (or IPersistStreamInit::GetSizeMax) */
-CPH_METHOD(GetMaxStreamSize)
-{
-       HRESULT res;
-       ULARGE_INTEGER size;
-       CPH_FETCH();
-       
-       CPH_NO_OBJ();
-       
-       res = get_persist_stream_init(helper);
-       if (helper->ipsi) {
-               res = IPersistStreamInit_GetSizeMax(helper->ipsi, &size);
-       } else {
-               res = get_persist_stream(helper);
-               if (helper->ips) {
-                       res = IPersistStream_GetSizeMax(helper->ips, &size);
-               } else {
-                       php_com_throw_exception(res, NULL TSRMLS_CC);
-                       return;
-               }
-       }
-
-       if (res != S_OK) {
-               php_com_throw_exception(res, NULL TSRMLS_CC);
-       } else {
-               /* TODO: handle 64 bit properly */
-               RETURN_LONG((LONG)size.QuadPart);
-       }
-}
-/* }}} */
-
-/* {{{ proto int COMPersistHelper::InitNew()
-   Initializes the object to a default state, via IPersistStreamInit::InitNew 
*/
-CPH_METHOD(InitNew)
-{
-       HRESULT res;
-       CPH_FETCH();
-       
-       CPH_NO_OBJ();
-
-       res = get_persist_stream_init(helper);
-       if (helper->ipsi) {
-               res = IPersistStreamInit_InitNew(helper->ipsi);
-
-               if (res != S_OK) {
-                       php_com_throw_exception(res, NULL TSRMLS_CC);
-               } else {
-                       RETURN_TRUE;
-               }
-       } else {
-               php_com_throw_exception(res, NULL TSRMLS_CC);
-       }
-}
-/* }}} */
-
-/* {{{ proto mixed COMPersistHelper::LoadFromStream(resource stream)
-   Initializes an object from the stream where it was previously saved, via 
IPersistStream::Load or OleLoadFromStream */
-CPH_METHOD(LoadFromStream)
-{
-       zval *zstm;
-       php_stream *stream;
-       IStream *stm = NULL;
-       HRESULT res;
-       CPH_FETCH();
-       
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", 
&zstm)) {
-               php_com_throw_exception(E_INVALIDARG, "invalid arguments" 
TSRMLS_CC);
-               return;
-       }
-
-       php_stream_from_zval_no_verify(stream, &zstm);
-       
-       if (stream == NULL) {
-               php_com_throw_exception(E_INVALIDARG, "expected a stream" 
TSRMLS_CC);
-               return;
-       }
-
-       stm = php_com_wrapper_export_stream(stream TSRMLS_CC);
-       if (stm == NULL) {
-               php_com_throw_exception(E_UNEXPECTED, "failed to wrap stream" 
TSRMLS_CC);
-               return;
-       }
-       
-       res = S_OK;
-       RETVAL_TRUE;
-
-       if (helper->unk == NULL) {
-               IDispatch *disp = NULL;
-
-               /* we need to create an object and load using OleLoadFromStream 
*/
-               res = OleLoadFromStream(stm, &IID_IDispatch, &disp);
-
-               if (SUCCEEDED(res)) {
-                       php_com_wrap_dispatch(return_value, disp, 
COMG(code_page) TSRMLS_CC);   
-               }
-       } else {
-               res = get_persist_stream_init(helper);
-               if (helper->ipsi) {
-                       res = IPersistStreamInit_Load(helper->ipsi, stm);
-               } else {
-                       res = get_persist_stream(helper);
-                       if (helper->ips) {
-                               res = IPersistStreamInit_Load(helper->ipsi, 
stm);
-                       }
-               }
-       }
-       IStream_Release(stm);
-
-       if (FAILED(res)) {
-               php_com_throw_exception(res, NULL TSRMLS_CC);
-               RETURN_NULL();
-       }
-}
-/* }}} */
-
-/* {{{ proto int COMPersistHelper::SaveToStream(resource stream)
-   Saves the object to a stream, via IPersistStream::Save */
-CPH_METHOD(SaveToStream)
-{
-       zval *zstm;
-       php_stream *stream;
-       IStream *stm = NULL;
-       HRESULT res;
-       CPH_FETCH();
-       
-       CPH_NO_OBJ();
-       
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", 
&zstm)) {
-               php_com_throw_exception(E_INVALIDARG, "invalid arguments" 
TSRMLS_CC);
-               return;
-       }
-
-       php_stream_from_zval_no_verify(stream, &zstm);
-       
-       if (stream == NULL) {
-               php_com_throw_exception(E_INVALIDARG, "expected a stream" 
TSRMLS_CC);
-               return;
-       }
-
-       stm = php_com_wrapper_export_stream(stream TSRMLS_CC);
-       if (stm == NULL) {
-               php_com_throw_exception(E_UNEXPECTED, "failed to wrap stream" 
TSRMLS_CC);
-               return;
-       }
-       
-       res = get_persist_stream_init(helper);
-       if (helper->ipsi) {
-               res = IPersistStreamInit_Save(helper->ipsi, stm, TRUE);
-       } else {
-               res = get_persist_stream(helper);
-               if (helper->ips) {
-                       res = IPersistStream_Save(helper->ips, stm, TRUE);
-               }
-       }
-       
-       IStream_Release(stm);
-
-       if (FAILED(res)) {
-               php_com_throw_exception(res, NULL TSRMLS_CC);
-               return;
-       }
-
-       RETURN_TRUE;
-}
-/* }}} */
-
-/* {{{ proto int COMPersistHelper::__construct([object com_object])
-   Creates a persistence helper object, usually associated with a com_object */
-CPH_METHOD(__construct)
-{
-       php_com_dotnet_object *obj = NULL;
-       zval *zobj = NULL;
-       CPH_FETCH();
-
-       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O!",
-                               &zobj, php_com_variant_class_entry)) {
-               php_com_throw_exception(E_INVALIDARG, "invalid arguments" 
TSRMLS_CC);
-               return;
-       }
-
-       if (!zobj) {
-               return;
-       }
-       
-       obj = CDNO_FETCH(zobj);
-
-       if (V_VT(&obj->v) != VT_DISPATCH || V_DISPATCH(&obj->v) == NULL) {
-               php_com_throw_exception(E_INVALIDARG, "parameter must represent 
an IDispatch COM object" TSRMLS_CC);
-               return;
-       }
-
-       /* it is always safe to cast an interface to IUnknown */
-       helper->unk = (IUnknown*)V_DISPATCH(&obj->v);
-       IUnknown_AddRef(helper->unk);
-       helper->codepage = obj->code_page;
-}
-/* }}} */
-
-
-
-
-static zend_function_entry com_persist_helper_methods[] = {
-       CPH_ME(__construct, NULL)
-       CPH_ME(GetCurFileName, NULL)
-       CPH_ME(SaveToFile, NULL)
-       CPH_ME(LoadFromFile, NULL)
-       CPH_ME(GetMaxStreamSize, NULL)
-       CPH_ME(InitNew, NULL)
-       CPH_ME(LoadFromStream, NULL)
-       CPH_ME(SaveToStream, NULL)
-       {NULL, NULL, NULL}
-};
-
-static void helper_free_storage(void *obj TSRMLS_DC)
-{
-       php_com_persist_helper *object = (php_com_persist_helper*)obj;
-
-       if (object->ipf) {
-               IPersistFile_Release(object->ipf);
-       }
-       if (object->ips) {
-               IPersistStream_Release(object->ips);
-       }
-       if (object->ipsi) {
-               IPersistStreamInit_Release(object->ipsi);
-       }
-       if (object->unk) {
-               IUnknown_Release(object->unk);
-       }
-       zend_hash_destroy(object->std.properties);
-       FREE_HASHTABLE(object->std.properties);
-       efree(object);
-}
-
-
-static void helper_clone(void *obj, void **clone_ptr TSRMLS_DC)
-{
-       php_com_persist_helper *clone, *object = (php_com_persist_helper*)obj;
-       zval *tmp;
-
-       clone = emalloc(sizeof(*object));
-       memcpy(clone, object, sizeof(*object));
-       *clone_ptr = clone;
-
-       ALLOC_HASHTABLE(clone->std.properties);
-       zend_hash_init(clone->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
-       
-       if (clone->ipf) {
-               IPersistFile_AddRef(clone->ipf);
-       }
-       if (clone->ips) {
-               IPersistStream_AddRef(clone->ips);
-       }
-       if (clone->ipsi) {
-               IPersistStreamInit_AddRef(clone->ipsi);
-       }
-       if (clone->unk) {
-               IUnknown_AddRef(clone->unk);
-       }
-}
-
-static zend_object_value helper_new(zend_class_entry *ce TSRMLS_DC)
-{
-       php_com_persist_helper *helper;
-       zend_object_value retval;
-       zval *tmp;
-
-       helper = emalloc(sizeof(*helper));
-       memset(helper, 0, sizeof(*helper));
-
-       ALLOC_HASHTABLE(helper->std.properties);
-       zend_hash_init(helper->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
-       helper->std.ce = helper_ce;
-       
-       retval.handle = zend_objects_store_put(helper, NULL, 
helper_free_storage, helper_clone TSRMLS_CC);
-       retval.handlers = &helper_handlers;
-
-       return retval;
-}
-
-int php_com_persist_minit(INIT_FUNC_ARGS)
-{
-       zend_class_entry ce;
-
-       memcpy(&helper_handlers, zend_get_std_object_handlers(), 
sizeof(helper_handlers));
-       helper_handlers.clone_obj = NULL;
-
-       INIT_CLASS_ENTRY(ce, "COMPersistHelper", com_persist_helper_methods);
-       ce.create_object = helper_new;
-       helper_ce = zend_register_internal_class(&ce TSRMLS_CC);
-       helper_ce->ce_flags |= ZEND_ACC_FINAL;
-
-       le_istream = zend_register_list_destructors_ex(istream_dtor,
-                       NULL, "com_dotnet_istream_wrapper", module_number);
-       
-       return SUCCESS;
-}
-
-/*
- * Local variables:
- * tab-width: 4
- * c-basic-offset: 4
- * End:
- * vim600: noet sw=4 ts=4 fdm=marker
- * vim<600: noet sw=4 ts=4
- */
+/*
+   +----------------------------------------------------------------------+
+   | PHP Version 5                                                        |
+   +----------------------------------------------------------------------+
+   | Copyright (c) 1997-2004 The PHP Group                                |
+   +----------------------------------------------------------------------+
+   | This source file is subject to version 3.0 of the PHP license,       |
+   | that is bundled with this package in the file LICENSE, and is        |
+   | available through the world-wide-web at the following url:           |
+   | http://www.php.net/license/3_0.txt.                                  |
+   | If you did not receive a copy of the PHP license and are unable to   |
+   | obtain it through the world-wide-web, please send a note to          |
+   | [EMAIL PROTECTED] so we can mail you a copy immediately.               |
+   +----------------------------------------------------------------------+
+   | Author: Wez Furlong  <[EMAIL PROTECTED]>                          |
+   +----------------------------------------------------------------------+
+ */
+
+/* $Id: com_persist.c,v 1.2.2.1 2006/02/01 07:42:40 sebastian Exp $ */
+
+/* Infrastructure for working with persistent COM objects.
+ * Implements: IStream* wrapper for PHP streams.
+ * TODO: Magic __wakeup and __sleep handlers for serialization 
+ * (can wait till 5.1) */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "php.h"
+#include "php_ini.h"
+#include "ext/standard/info.h"
+#include "php_com_dotnet.h"
+#include "php_com_dotnet_internal.h"
+#include "Zend/zend_exceptions.h"
+
+/* {{{ expose php_stream as a COM IStream */
+
+typedef struct {
+       CONST_VTBL struct IStreamVtbl *lpVtbl;
+       THREAD_T engine_thread;
+       LONG refcount;
+       php_stream *stream;
+       int id;
+} php_istream;
+
+static int le_istream;
+static void istream_destructor(php_istream *stm);
+
+static void istream_dtor(zend_rsrc_list_entry *rsrc TSRMLS_DC)
+{
+       php_istream *stm = (php_istream *)rsrc->ptr;
+       istream_destructor(stm);
+}
+
+#define FETCH_STM()    \
+       php_istream *stm = (php_istream*)This; \
+       if (tsrm_thread_id() != stm->engine_thread) \
+               return E_UNEXPECTED;
+
+static HRESULT STDMETHODCALLTYPE stm_queryinterface(
+       IStream *This,
+       /* [in] */ REFIID riid,
+       /* [iid_is][out] */ void **ppvObject)
+{
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       if (IsEqualGUID(&IID_IUnknown, riid) ||
+                       IsEqualGUID(&IID_IStream, riid)) {
+               *ppvObject = This;
+               InterlockedIncrement(&stm->refcount);
+               return S_OK;
+       }
+
+       *ppvObject = NULL;
+       return E_NOINTERFACE;
+}
+
+static ULONG STDMETHODCALLTYPE stm_addref(IStream *This)
+{
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       return InterlockedIncrement(&stm->refcount);
+}
+        
+static ULONG STDMETHODCALLTYPE stm_release(IStream *This)
+{
+       ULONG ret;
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       ret = InterlockedDecrement(&stm->refcount);
+       if (ret == 0) {
+               /* destroy it */
+               if (stm->id)
+                       zend_list_delete(stm->id);
+       }
+       return ret;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_read(IStream *This, void *pv, ULONG cb, 
ULONG *pcbRead)
+{
+       int nread;
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       nread = php_stream_read(stm->stream, pv, cb);
+
+       if (pcbRead) {
+               *pcbRead = nread > 0 ? nread : 0;
+       }
+       if (nread > 0) {
+               return S_OK;
+       }
+       return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_write(IStream *This, void const *pv, 
ULONG cb, ULONG *pcbWritten)
+{
+       int nwrote;
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       nwrote = php_stream_write(stm->stream, pv, cb);
+
+       if (pcbWritten) {
+               *pcbWritten = nwrote > 0 ? nwrote : 0;
+       }
+       if (nwrote > 0) {
+               return S_OK;
+       }
+       return S_FALSE;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_seek(IStream *This, LARGE_INTEGER 
dlibMove,
+               DWORD dwOrigin, ULARGE_INTEGER *plibNewPosition)
+{
+       off_t offset;
+       int whence;
+       int ret;
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       switch (dwOrigin) {
+               case STREAM_SEEK_SET:   whence = SEEK_SET;      break;
+               case STREAM_SEEK_CUR:   whence = SEEK_CUR;      break;
+               case STREAM_SEEK_END:   whence = SEEK_END;      break;
+               default:
+                       return STG_E_INVALIDFUNCTION;
+       }
+       
+       if (dlibMove.HighPart) {
+               /* we don't support 64-bit offsets */
+               return STG_E_INVALIDFUNCTION;
+       }
+       
+       offset = dlibMove.QuadPart;
+
+       ret = php_stream_seek(stm->stream, offset, whence);
+
+       if (plibNewPosition) {
+               plibNewPosition->QuadPart = (ULONGLONG)(ret >= 0 ? ret : 0);
+       }
+
+       return ret >= 0 ? S_OK : STG_E_INVALIDFUNCTION;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_set_size(IStream *This, ULARGE_INTEGER 
libNewSize)
+{
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       if (libNewSize.HighPart) {
+               return STG_E_INVALIDFUNCTION;
+       }
+       
+       if (php_stream_truncate_supported(stm->stream)) {
+               int ret = php_stream_truncate_set_size(stm->stream, 
(size_t)libNewSize.QuadPart);
+
+               if (ret == 0) {
+                       return S_OK;
+               }
+       }
+
+       return STG_E_INVALIDFUNCTION;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_copy_to(IStream *This, IStream *pstm, 
ULARGE_INTEGER cb,
+               ULARGE_INTEGER *pcbRead, ULARGE_INTEGER *pcbWritten)
+{
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       return E_NOTIMPL;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_commit(IStream *This, DWORD 
grfCommitFlags)
+{
+       TSRMLS_FETCH();
+       FETCH_STM();
+
+       php_stream_flush(stm->stream);
+
+       return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_revert(IStream *This)
+{
+       /* NOP */
+       return S_OK;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_lock_region(IStream *This,
+       ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD lockType)
+{
+       return STG_E_INVALIDFUNCTION;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_unlock_region(IStream *This,
+               ULARGE_INTEGER libOffset, ULARGE_INTEGER cb, DWORD lockType)
+{
+       return STG_E_INVALIDFUNCTION;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_stat(IStream *This,
+               STATSTG *pstatstg, DWORD grfStatFlag)
+{
+       return STG_E_INVALIDFUNCTION;
+}
+
+static HRESULT STDMETHODCALLTYPE stm_clone(IStream *This, IStream **ppstm)
+{
+       return STG_E_INVALIDFUNCTION;
+}
+
+static struct IStreamVtbl php_istream_vtbl = {
+       stm_queryinterface,
+       stm_addref,
+       stm_release,
+       stm_read,
+       stm_write,
+       stm_seek,
+       stm_set_size,
+       stm_copy_to,
+       stm_commit,
+       stm_revert,
+       stm_lock_region,
+       stm_unlock_region,
+       stm_stat,
+       stm_clone
+};
+
+static void istream_destructor(php_istream *stm)
+{
+       TSRMLS_FETCH();
+
+       if (stm->id) {
+               int id = stm->id;
+               stm->id = 0;
+               zend_list_delete(id);
+               return;
+       }
+
+       if (stm->refcount > 0) {
+               CoDisconnectObject((IUnknown*)stm, 0);
+       }
+
+       zend_list_delete(stm->stream->rsrc_id);
+
+       CoTaskMemFree(stm);
+}
+/* }}} */
+
+PHPAPI IStream *php_com_wrapper_export_stream(php_stream *stream TSRMLS_DC)
+{
+       php_istream *stm = (php_istream*)CoTaskMemAlloc(sizeof(*stm));
+
+       if (stm == NULL)
+               return NULL;
+
+       memset(stm, 0, sizeof(*stm));
+       stm->engine_thread = tsrm_thread_id();
+       stm->lpVtbl = &php_istream_vtbl;
+       stm->refcount = 1;
+       stm->stream = stream;
+
+       zend_list_addref(stream->rsrc_id);
+       stm->id = zend_list_insert(stm, le_istream);
+
+       return (IStream*)stm;
+}
+
+#define CPH_ME(fname, arginfo) PHP_ME(com_persist, fname, arginfo, 
ZEND_ACC_PUBLIC)
+#define CPH_SME(fname, arginfo)        PHP_ME(com_persist, fname, arginfo, 
ZEND_ACC_ALLOW_STATIC|ZEND_ACC_PUBLIC)
+#define CPH_METHOD(fname)              static PHP_METHOD(com_persist, fname)
+       
+#define CPH_FETCH()                            php_com_persist_helper *helper 
= (php_com_persist_helper*)zend_object_store_get_object(getThis() TSRMLS_CC);
+
+#define CPH_NO_OBJ()                   if (helper->unk == NULL) { 
php_com_throw_exception(E_INVALIDARG, "No COM object is associated with this 
helper instance" TSRMLS_CC); return; }
+
+typedef struct {
+       zend_object                     std;
+       long codepage;
+       IUnknown                        *unk;
+       IPersistStream          *ips;
+       IPersistStreamInit      *ipsi;
+       IPersistFile            *ipf;
+} php_com_persist_helper;
+
+static zend_object_handlers helper_handlers;
+static zend_class_entry *helper_ce;
+
+static inline HRESULT get_persist_stream(php_com_persist_helper *helper)
+{
+       if (!helper->ips && helper->unk) {
+               return IUnknown_QueryInterface(helper->unk, 
&IID_IPersistStream, &helper->ips);
+       }
+       return helper->ips ? S_OK : E_NOTIMPL;
+}
+
+static inline HRESULT get_persist_stream_init(php_com_persist_helper *helper)
+{
+       if (!helper->ipsi && helper->unk) {
+               return IUnknown_QueryInterface(helper->unk, 
&IID_IPersistStreamInit, &helper->ipsi);
+       }
+       return helper->ipsi ? S_OK : E_NOTIMPL;
+}
+
+static inline HRESULT get_persist_file(php_com_persist_helper *helper)
+{
+       if (!helper->ipf && helper->unk) {
+               return IUnknown_QueryInterface(helper->unk, &IID_IPersistFile, 
&helper->ipf);
+       }
+       return helper->ipf ? S_OK : E_NOTIMPL;
+}
+
+
+/* {{{ proto string COMPersistHelper::GetCurFile()
+   Determines the filename into which an object will be saved, or false if 
none is set, via IPersistFile::GetCurFile */
+CPH_METHOD(GetCurFileName)
+{
+       HRESULT res;
+       OLECHAR *olename = NULL;
+       CPH_FETCH();
+
+       CPH_NO_OBJ();
+       
+       res = get_persist_file(helper);
+       if (helper->ipf) {
+               res = IPersistFile_GetCurFile(helper->ipf, &olename);
+
+               if (res == S_OK) {
+                       Z_TYPE_P(return_value) = IS_STRING;
+                       Z_STRVAL_P(return_value) = 
php_com_olestring_to_string(olename,
+                                  &Z_STRLEN_P(return_value), helper->codepage 
TSRMLS_CC);
+                       CoTaskMemFree(olename);
+                       return;
+               } else if (res == S_FALSE) {
+                       CoTaskMemFree(olename);
+                       RETURN_FALSE;
+               }
+               php_com_throw_exception(res, NULL TSRMLS_CC);
+       } else {
+               php_com_throw_exception(res, NULL TSRMLS_CC);
+       }
+}
+/* }}} */
+
+
+/* {{{ proto bool COMPersistHelper::SaveToFile(string filename [, bool 
remember])
+   Persist object data to file, via IPersistFile::Save */
+CPH_METHOD(SaveToFile)
+{
+       HRESULT res;
+       char *filename, *fullpath = NULL;
+       int filename_len;
+       zend_bool remember = TRUE;
+       OLECHAR *olefilename = NULL;
+       CPH_FETCH();
+       
+       CPH_NO_OBJ();
+
+       res = get_persist_file(helper);
+       if (helper->ipf) {
+               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
"s!|b",
+                                       &filename, &filename_len, &remember)) {
+                       php_com_throw_exception(E_INVALIDARG, "Invalid 
arguments" TSRMLS_CC);
+                       return;
+               }
+
+               if (filename) {
+                       fullpath = expand_filepath(filename, NULL TSRMLS_CC);
+       
+                       if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, 
CHECKUID_CHECK_FILE_AND_DIR))) {
+                               RETURN_FALSE;
+                       }
+
+                       if (php_check_open_basedir(fullpath TSRMLS_CC)) {
+                               RETURN_FALSE;
+                       }
+                       
+                       olefilename = php_com_string_to_olestring(filename, 
strlen(fullpath), helper->codepage TSRMLS_CC);
+                       efree(fullpath);
+               }
+               res = IPersistFile_Save(helper->ipf, olefilename, remember);
+               if (SUCCEEDED(res)) {
+                       if (!olefilename) {
+                               res = IPersistFile_GetCurFile(helper->ipf, 
&olefilename);
+                               if (S_OK == res) {
+                                       IPersistFile_SaveCompleted(helper->ipf, 
olefilename);
+                                       CoTaskMemFree(olefilename);
+                                       olefilename = NULL;
+                               }
+                       } else if (remember) {
+                               IPersistFile_SaveCompleted(helper->ipf, 
olefilename);
+                       }
+               }
+                       
+               if (olefilename) {
+                       efree(olefilename);
+               }
+
+               if (FAILED(res)) {
+                       php_com_throw_exception(res, NULL TSRMLS_CC);
+               }
+
+       } else {
+               php_com_throw_exception(res, NULL TSRMLS_CC);
+       }
+}
+/* }}} */
+
+/* {{{ proto bool COMPersistHelper::LoadFromFile(string filename [, int flags])
+   Load object data from file, via IPersistFile::Load */
+CPH_METHOD(LoadFromFile)
+{
+       HRESULT res;
+       char *filename, *fullpath;
+       int filename_len;
+       long flags = 0;
+       OLECHAR *olefilename;
+       CPH_FETCH();
+       
+       CPH_NO_OBJ();
+
+       res = get_persist_file(helper);
+       if (helper->ipf) {
+
+               if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, 
"s|l",
+                                       &filename, &filename_len, &flags)) {
+                       php_com_throw_exception(E_INVALIDARG, "Invalid 
arguments" TSRMLS_CC);
+                       return;
+               }
+
+               fullpath = expand_filepath(filename, NULL TSRMLS_CC);
+
+               if (PG(safe_mode) && (!php_checkuid(fullpath, NULL, 
CHECKUID_CHECK_FILE_AND_DIR))) {
+                       RETURN_FALSE;
+               }
+
+               if (php_check_open_basedir(fullpath TSRMLS_CC)) {
+                       RETURN_FALSE;
+               }
+
+               olefilename = php_com_string_to_olestring(fullpath, 
strlen(fullpath), helper->codepage TSRMLS_CC);
+               efree(fullpath);
+                       
+               res = IPersistFile_Load(helper->ipf, olefilename, flags);
+               efree(olefilename);
+
+               if (FAILED(res)) {
+                       php_com_throw_exception(res, NULL TSRMLS_CC);
+               }
+               
+       } else {
+               php_com_throw_exception(res, NULL TSRMLS_CC);
+       }
+}
+/* }}} */
+
+/* {{{ proto int COMPersistHelper::GetMaxStreamSize()
+   Gets maximum stream size required to store the object data, via 
IPersistStream::GetSizeMax (or IPersistStreamInit::GetSizeMax) */
+CPH_METHOD(GetMaxStreamSize)
+{
+       HRESULT res;
+       ULARGE_INTEGER size;
+       CPH_FETCH();
+       
+       CPH_NO_OBJ();
+       
+       res = get_persist_stream_init(helper);
+       if (helper->ipsi) {
+               res = IPersistStreamInit_GetSizeMax(helper->ipsi, &size);
+       } else {
+               res = get_persist_stream(helper);
+               if (helper->ips) {
+                       res = IPersistStream_GetSizeMax(helper->ips, &size);
+               } else {
+                       php_com_throw_exception(res, NULL TSRMLS_CC);
+                       return;
+               }
+       }
+
+       if (res != S_OK) {
+               php_com_throw_exception(res, NULL TSRMLS_CC);
+       } else {
+               /* TODO: handle 64 bit properly */
+               RETURN_LONG((LONG)size.QuadPart);
+       }
+}
+/* }}} */
+
+/* {{{ proto int COMPersistHelper::InitNew()
+   Initializes the object to a default state, via IPersistStreamInit::InitNew 
*/
+CPH_METHOD(InitNew)
+{
+       HRESULT res;
+       CPH_FETCH();
+       
+       CPH_NO_OBJ();
+
+       res = get_persist_stream_init(helper);
+       if (helper->ipsi) {
+               res = IPersistStreamInit_InitNew(helper->ipsi);
+
+               if (res != S_OK) {
+                       php_com_throw_exception(res, NULL TSRMLS_CC);
+               } else {
+                       RETURN_TRUE;
+               }
+       } else {
+               php_com_throw_exception(res, NULL TSRMLS_CC);
+       }
+}
+/* }}} */
+
+/* {{{ proto mixed COMPersistHelper::LoadFromStream(resource stream)
+   Initializes an object from the stream where it was previously saved, via 
IPersistStream::Load or OleLoadFromStream */
+CPH_METHOD(LoadFromStream)
+{
+       zval *zstm;
+       php_stream *stream;
+       IStream *stm = NULL;
+       HRESULT res;
+       CPH_FETCH();
+       
+       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", 
&zstm)) {
+               php_com_throw_exception(E_INVALIDARG, "invalid arguments" 
TSRMLS_CC);
+               return;
+       }
+
+       php_stream_from_zval_no_verify(stream, &zstm);
+       
+       if (stream == NULL) {
+               php_com_throw_exception(E_INVALIDARG, "expected a stream" 
TSRMLS_CC);
+               return;
+       }
+
+       stm = php_com_wrapper_export_stream(stream TSRMLS_CC);
+       if (stm == NULL) {
+               php_com_throw_exception(E_UNEXPECTED, "failed to wrap stream" 
TSRMLS_CC);
+               return;
+       }
+       
+       res = S_OK;
+       RETVAL_TRUE;
+
+       if (helper->unk == NULL) {
+               IDispatch *disp = NULL;
+
+               /* we need to create an object and load using OleLoadFromStream 
*/
+               res = OleLoadFromStream(stm, &IID_IDispatch, &disp);
+
+               if (SUCCEEDED(res)) {
+                       php_com_wrap_dispatch(return_value, disp, 
COMG(code_page) TSRMLS_CC);   
+               }
+       } else {
+               res = get_persist_stream_init(helper);
+               if (helper->ipsi) {
+                       res = IPersistStreamInit_Load(helper->ipsi, stm);
+               } else {
+                       res = get_persist_stream(helper);
+                       if (helper->ips) {
+                               res = IPersistStreamInit_Load(helper->ipsi, 
stm);
+                       }
+               }
+       }
+       IStream_Release(stm);
+
+       if (FAILED(res)) {
+               php_com_throw_exception(res, NULL TSRMLS_CC);
+               RETURN_NULL();
+       }
+}
+/* }}} */
+
+/* {{{ proto int COMPersistHelper::SaveToStream(resource stream)
+   Saves the object to a stream, via IPersistStream::Save */
+CPH_METHOD(SaveToStream)
+{
+       zval *zstm;
+       php_stream *stream;
+       IStream *stm = NULL;
+       HRESULT res;
+       CPH_FETCH();
+       
+       CPH_NO_OBJ();
+       
+       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", 
&zstm)) {
+               php_com_throw_exception(E_INVALIDARG, "invalid arguments" 
TSRMLS_CC);
+               return;
+       }
+
+       php_stream_from_zval_no_verify(stream, &zstm);
+       
+       if (stream == NULL) {
+               php_com_throw_exception(E_INVALIDARG, "expected a stream" 
TSRMLS_CC);
+               return;
+       }
+
+       stm = php_com_wrapper_export_stream(stream TSRMLS_CC);
+       if (stm == NULL) {
+               php_com_throw_exception(E_UNEXPECTED, "failed to wrap stream" 
TSRMLS_CC);
+               return;
+       }
+       
+       res = get_persist_stream_init(helper);
+       if (helper->ipsi) {
+               res = IPersistStreamInit_Save(helper->ipsi, stm, TRUE);
+       } else {
+               res = get_persist_stream(helper);
+               if (helper->ips) {
+                       res = IPersistStream_Save(helper->ips, stm, TRUE);
+               }
+       }
+       
+       IStream_Release(stm);
+
+       if (FAILED(res)) {
+               php_com_throw_exception(res, NULL TSRMLS_CC);
+               return;
+       }
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+/* {{{ proto int COMPersistHelper::__construct([object com_object])
+   Creates a persistence helper object, usually associated with a com_object */
+CPH_METHOD(__construct)
+{
+       php_com_dotnet_object *obj = NULL;
+       zval *zobj = NULL;
+       CPH_FETCH();
+
+       if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O!",
+                               &zobj, php_com_variant_class_entry)) {
+               php_com_throw_exception(E_INVALIDARG, "invalid arguments" 
TSRMLS_CC);
+               return;
+       }
+
+       if (!zobj) {
+               return;
+       }
+       
+       obj = CDNO_FETCH(zobj);
+
+       if (V_VT(&obj->v) != VT_DISPATCH || V_DISPATCH(&obj->v) == NULL) {
+               php_com_throw_exception(E_INVALIDARG, "parameter must represent 
an IDispatch COM object" TSRMLS_CC);
+               return;
+       }
+
+       /* it is always safe to cast an interface to IUnknown */
+       helper->unk = (IUnknown*)V_DISPATCH(&obj->v);
+       IUnknown_AddRef(helper->unk);
+       helper->codepage = obj->code_page;
+}
+/* }}} */
+
+
+
+
+static zend_function_entry com_persist_helper_methods[] = {
+       CPH_ME(__construct, NULL)
+       CPH_ME(GetCurFileName, NULL)
+       CPH_ME(SaveToFile, NULL)
+       CPH_ME(LoadFromFile, NULL)
+       CPH_ME(GetMaxStreamSize, NULL)
+       CPH_ME(InitNew, NULL)
+       CPH_ME(LoadFromStream, NULL)
+       CPH_ME(SaveToStream, NULL)
+       {NULL, NULL, NULL}
+};
+
+static void helper_free_storage(void *obj TSRMLS_DC)
+{
+       php_com_persist_helper *object = (php_com_persist_helper*)obj;
+
+       if (object->ipf) {
+               IPersistFile_Release(object->ipf);
+       }
+       if (object->ips) {
+               IPersistStream_Release(object->ips);
+       }
+       if (object->ipsi) {
+               IPersistStreamInit_Release(object->ipsi);
+       }
+       if (object->unk) {
+               IUnknown_Release(object->unk);
+       }
+       zend_hash_destroy(object->std.properties);
+       FREE_HASHTABLE(object->std.properties);
+       efree(object);
+}
+
+
+static void helper_clone(void *obj, void **clone_ptr TSRMLS_DC)
+{
+       php_com_persist_helper *clone, *object = (php_com_persist_helper*)obj;
+       zval *tmp;
+
+       clone = emalloc(sizeof(*object));
+       memcpy(clone, object, sizeof(*object));
+       *clone_ptr = clone;
+
+       ALLOC_HASHTABLE(clone->std.properties);
+       zend_hash_init(clone->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
+       
+       if (clone->ipf) {
+               IPersistFile_AddRef(clone->ipf);
+       }
+       if (clone->ips) {
+               IPersistStream_AddRef(clone->ips);
+       }
+       if (clone->ipsi) {
+               IPersistStreamInit_AddRef(clone->ipsi);
+       }
+       if (clone->unk) {
+               IUnknown_AddRef(clone->unk);
+       }
+}
+
+static zend_object_value helper_new(zend_class_entry *ce TSRMLS_DC)
+{
+       php_com_persist_helper *helper;
+       zend_object_value retval;
+       zval *tmp;
+
+       helper = emalloc(sizeof(*helper));
+       memset(helper, 0, sizeof(*helper));
+
+       ALLOC_HASHTABLE(helper->std.properties);
+       zend_hash_init(helper->std.properties, 0, NULL, ZVAL_PTR_DTOR, 0);
+       helper->std.ce = helper_ce;
+       
+       retval.handle = zend_objects_store_put(helper, NULL, 
helper_free_storage, helper_clone TSRMLS_CC);
+       retval.handlers = &helper_handlers;
+
+       return retval;
+}
+
+int php_com_persist_minit(INIT_FUNC_ARGS)
+{
+       zend_class_entry ce;
+
+       memcpy(&helper_handlers, zend_get_std_object_handlers(), 
sizeof(helper_handlers));
+       helper_handlers.clone_obj = NULL;
+
+       INIT_CLASS_ENTRY(ce, "COMPersistHelper", com_persist_helper_methods);
+       ce.create_object = helper_new;
+       helper_ce = zend_register_internal_class(&ce TSRMLS_CC);
+       helper_ce->ce_flags |= ZEND_ACC_FINAL;
+
+       le_istream = zend_register_list_destructors_ex(istream_dtor,
+                       NULL, "com_dotnet_istream_wrapper", module_number);
+       
+       return SUCCESS;
+}
+
+/*
+ * Local variables:
+ * tab-width: 4
+ * c-basic-offset: 4
+ * End:
+ * vim600: noet sw=4 ts=4 fdm=marker
+ * vim<600: noet sw=4 ts=4
+ */

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to