1 /////////////////////////////////////////////////////////////////////////////
2 // Name: cpp/streams.cpp
3 // Purpose: implementation for streams.h
4 // Author: Mattia Barbon
7 // RCS-ID: $Id: streams.cpp 2698 2009-12-13 11:08:53Z mbarbon $
8 // Copyright: (c) 2001-2002, 2004, 2006-2007, 2009 Mattia Barbon
9 // Licence: This program is free software; you can redistribute it and/or
10 // modify it under the same terms as Perl itself
11 /////////////////////////////////////////////////////////////////////////////
13 #if WXPERL_W_VERSION_GE( 2, 5, 3 )
14 typedef wxFileOffset wxPliFileOffset;
16 typedef off_t wxPliFileOffset;
20 const char sub_read[] = "sub { read $_[0], $_[1], $_[2] }";
21 const char sub_seek[] = "sub { seek $_[0], $_[1], $_[2]; tell $_[0] }";
22 const char sub_tell[] = "sub { tell $_[0] }";
23 const char sub_write[] = "sub { print { $_[0] } $_[1] }";
24 const char sub_length[] = "sub { eval { fileno( $_[0] ) && fileno( $_[0] ) >= 0 } ? ( stat $_[0] )[7] : -1 }";
32 class wxPliStreamInitializer
35 wxPliStreamInitializer()
38 sg_read = eval_pv( CHAR_P sub_read, 1 );
39 sg_seek = eval_pv( CHAR_P sub_seek, 1 );
40 sg_tell = eval_pv( CHAR_P sub_tell, 1 );
41 sg_write = eval_pv( CHAR_P sub_write, 1 );
42 sg_length = eval_pv( CHAR_P sub_length, 1 );
43 SvREFCNT_inc( sg_read );
44 SvREFCNT_inc( sg_seek );
45 SvREFCNT_inc( sg_tell );
46 SvREFCNT_inc( sg_write );
47 SvREFCNT_inc( sg_length );
50 ~wxPliStreamInitializer()
52 // SvREFCNT_dec( sg_read );
53 // SvREFCNT_dec( sg_seek );
54 // SvREFCNT_dec( sg_tell );
55 // SvREFCNT_dec( sg_write );
59 wxPliStreamInitializer dummy;
63 wxPliFileOffset stream_seek( wxStreamBase* stream, SV* fh, wxPliFileOffset seek, wxSeekMode mode );
64 wxPliFileOffset stream_tell( const wxStreamBase* stream, SV* fh );
65 wxPliFileOffset stream_length( const wxStreamBase* stream, SV* fh );
69 wxPliInputStream* wxPliInputStream_ctor( SV* sv )
71 return new wxPliInputStream( sv );
74 wxPliOutputStream* wxPliOutputStream_ctor( SV* sv )
76 return new wxPliOutputStream( sv );
79 wxPliInputStream::wxPliInputStream( SV* fh )
86 wxPliInputStream::wxPliInputStream( const wxPliInputStream& stream )
93 const wxPliInputStream& wxPliInputStream::operator =
94 ( const wxPliInputStream& stream )
97 if( m_fh ) SvREFCNT_dec( m_fh );
104 wxPliInputStream::~wxPliInputStream()
107 SvREFCNT_dec( m_fh );
110 size_t wxPliInputStream::OnSysRead( void* buffer, size_t size )
112 //FIXME// need a ( safe ) way to: create an SV, set ( NOT copy )
113 //FIXME// buffer into it, then call sg_read
121 SV* target = sv_2mortal( newSVsv( &PL_sv_undef ) );
126 XPUSHs( sv_2mortal( newSVuv( size ) ) );
129 call_sv( sg_read, G_SCALAR );
133 SV* sv_read_count = POPs;
134 size_t read_count = 0;
136 m_lasterror = wxSTREAM_NO_ERROR;
137 if( !SvOK( sv_read_count ) )
138 m_lasterror = wxSTREAM_READ_ERROR;
141 read_count = SvOK( target ) ? SvUV( sv_read_count ) : 0;
143 m_lasterror = wxSTREAM_EOF;
149 memcpy( buffer, SvPV_nolen( target ), read_count );
157 wxPliFileOffset wxPliInputStream::OnSysSeek( wxPliFileOffset seek, wxSeekMode mode )
159 return stream_seek( this, m_fh, seek, mode );
162 wxPliFileOffset wxPliInputStream::OnSysTell() const
164 return stream_tell( this, m_fh );
167 wxFileOffset wxPliInputStream::GetLength() const
169 return stream_length( this, m_fh );
172 size_t wxPliInputStream::GetSize() const
174 return stream_length( this, m_fh );
179 wxPliOutputStream::wxPliOutputStream( SV* fh )
183 SvREFCNT_inc( m_fh );
186 wxPliOutputStream::wxPliOutputStream( const wxPliOutputStream& stream )
190 SvREFCNT_inc( m_fh );
193 const wxPliOutputStream& wxPliOutputStream::operator =
194 ( const wxPliOutputStream& stream )
197 if( m_fh ) SvREFCNT_dec( m_fh );
199 SvREFCNT_inc( m_fh );
204 wxPliOutputStream::~wxPliOutputStream()
207 SvREFCNT_dec( m_fh );
210 size_t wxPliOutputStream::OnSysWrite( const void* buffer, size_t size )
212 //FIXME// need a ( safe ) way to: create an SV, set ( NOT copy )
213 //FIXME// buffer into it, then call sg_write
215 // printf( "OnSysWrite: %x %d = ", buffer, size );
223 SV* target = sv_2mortal( newSVpvn( CHAR_P ( const char*)buffer, size ) );
228 XPUSHs( sv_2mortal( newSVuv( size ) ) );
231 call_sv( sg_write, G_SCALAR );
235 SV* sv_write_count = POPs;
236 size_t write_count = 0;
238 m_lasterror = wxSTREAM_NO_ERROR;
239 if( !SvOK( sv_write_count ) )
240 m_lasterror = wxSTREAM_WRITE_ERROR;
243 write_count = SvUV( sv_write_count );
251 // printf( "%d\n", write_count );fflush( stdout );
252 // OnSysSeek( 0, wxFromCurrent );
257 wxPliFileOffset wxPliOutputStream::OnSysSeek( wxPliFileOffset seek, wxSeekMode mode )
259 return stream_seek( this, m_fh, seek, mode );
262 wxPliFileOffset wxPliOutputStream::OnSysTell() const
264 return stream_tell( this, m_fh );
267 wxFileOffset wxPliOutputStream::GetLength() const
269 return stream_length( this, m_fh );
272 size_t wxPliOutputStream::GetSize() const
274 return stream_length( this, m_fh );
279 wxPliFileOffset stream_seek( wxStreamBase* stream, SV* fh, wxPliFileOffset seek, wxSeekMode mode )
306 XPUSHs( sv_2mortal( newSViv( seek ) ) );
307 XPUSHs( sv_2mortal( newSViv( pl_act ) ) );
310 call_sv( sg_seek, G_SCALAR );
322 wxPliFileOffset stream_tell( const wxStreamBase* stream, SV* fh )
334 call_sv( sg_tell, G_SCALAR );
346 wxPliFileOffset stream_length( const wxStreamBase* stream, SV* fh )
358 call_sv( sg_length, G_SCALAR );
367 return ret == -1 ? ~0 : ret;