📄 buffers.h
字号:
/* Is an argument C<[]>, meaning we should pass C<NULL>? */#define null_arg(sv) ( SvROK(sv) && SVt_PVAV == SvTYPE(SvRV(sv)) \ && -1 == av_len((AV*)SvRV(sv)) )#define PV_or_null(sv) ( null_arg(sv) ? NULL : SvPV(sv,PL_na) )/* Minimum buffer size to use when no buffer existed: */#define MIN_GROW_SIZE 128#ifdef Debug/* Used in Debug() messages to show which macro call is involved: */#define string(arg) #arg#endif/* Simplify using SvGROW() for byte-sized buffers: */#define lSvGROW(sv,n) SvGROW( sv, 0==(n) ? MIN_GROW_SIZE : (n)+1 )/* Simplify using SvGROW() for WCHAR-sized buffers: */#define lwSvGROW(sv,n) CAST( WCHAR *, \ SvGROW( sv, sizeof(WCHAR)*( 0==(n) ? MIN_GROW_SIZE : (n)+1 ) ) )/* Whether the buffer size we got lets us change what buffer size we use: */#define autosize(sv) (!( SvOK(sv) && ! SvROK(sv) \ && SvPV(sv,PL_na) && '=' == *SvPV(sv,PL_na) ))/* Get the IV/UV for a parameter that might be C<[]> or C<undef>: */#define optIV(sv) ( null_arg(sv) ? 0 : !SvOK(sv) ? 0 : SvIV(sv) )#define optUV(sv) ( null_arg(sv) ? 0 : !SvOK(sv) ? 0 : SvUV(sv) )/* Allocate temporary storage that will automatically be freed later: */#ifndef TempAlloc /* Can be C<#define>d to be C<_alloca>, for example */# define TempAlloc( size ) sv_grow( sv_newmortal(), size )#endif/* Initialize a buffer size argument of type (DWORD *): */#define init_buf_pl( plSize, svSize, tpSize ) STMT_START { \ if( null_arg(svSize) ) \ plSize= NULL; \ else { \ STRLEN n_a; \ *( plSize= CAST( tpSize, TempAlloc(sizeof(*plSize)) ) )= \ autosize(svSize) ? optUV(svSize) \ : strtoul( 1+SvPV(svSize,n_a), NULL, 10 ); \ } } STMT_END/* In INPUT section put ": init_buf_pl($var,$arg,$type);" after var name. *//* Initialize a buffer size argument of type DWORD: */#define init_buf_l( svSize ) \ ( null_arg(svSize) ? 0 : autosize(svSize) ? optUV(svSize) \ : strtoul( 1+SvPV(svSize,PL_na), NULL, 10 ) )/* In INPUT section put "= init_buf_l($arg);" after variable name. *//* Lengths in WCHARs are initialized the same as lengths in bytes: */#define init_buf_plw init_buf_pl#define init_buf_lw init_buf_l/* grow_buf_pl() and grow_buf_plw() are included so you can define * parameters of type C<DWORD *>, for example. In practice, it is * usually better to define such parameters as "DWORD &". *//* Grow a buffer where we have a pointer to its size in bytes: */#define grow_buf_pl( sBuf,svBuf,tpBuf, plSize,svSize,tpSize ) STMT_START { \ Debug(("grow_buf_pl( %s==0x%lX,[%s:%ld/%ld, %s==0x%lX:%ld,[%s )\n",\ string(sBuf),sBuf,strchr(string(svBuf),'('),SvPOK(svBuf)? \ SvCUR(svBuf):-1,SvPOK(svBuf)?SvLEN(svBuf):-1,string(plSize), \ plSize,plSize?*plSize:-1,strchr(string(svSize),'('))); \ if( null_arg(svBuf) ) { \ sBuf= NULL; \ } else { \ STRLEN n_a; \ if( NULL == plSize ) \ *( plSize= CAST(tpSize,TempAlloc(sizeof(*plSize))) )= 0;\ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ (void) SvPV_force( svBuf, n_a ); \ sBuf= CAST( tpBuf, lSvGROW( svBuf, *plSize ) ); \ if( autosize(svSize) ) *plSize= SvLEN(svBuf) - 1; \ Debug(("more buf_pl( %s==0x%lX,[%s:%ld/%ld, %s==0x%lX:%ld,[%s )\n",\ string(sBuf),sBuf,strchr(string(svBuf),'('),SvPOK(svBuf)? \ SvCUR(svBuf):-1,SvPOK(svBuf)?SvLEN(svBuf):-1,string(plSize),\ plSize,plSize?*plSize:-1,strchr(string(svSize),'('))); \ } } STMT_END/* Grow a buffer where we have a pointer to its size in WCHARs: */#define grow_buf_plw( sBuf,svBuf, plwSize,svSize,tpSize ) STMT_START { \ if( null_arg(svBuf) ) { \ sBuf= NULL; \ } else { \ STRLEN n_a; \ if( NULL == plwSize ) \ *( plwSize= CAST(tpSize,TempAlloc(sizeof(*plwSize))) )= 0;\ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ (void) SvPV_force( svBuf, n_a ); \ sBuf= lwSvGROW( svBuf, *plwSize ); \ if( autosize(svSize) ) \ *plwSize= SvLEN(svBuf)/sizeof(WCHAR) - 1; \ } } STMT_END/* Grow a buffer where we have its size in bytes: */#define grow_buf_l( sBuf,svBuf,tpBuf, lSize,svSize ) STMT_START { \ if( null_arg(svBuf) ) { \ sBuf= NULL; \ } else { \ STRLEN n_a; \ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ (void) SvPV_force( svBuf, n_a ); \ sBuf= CAST( tpBuf, lSvGROW( svBuf, lSize ) ); \ if( autosize(svSize) ) lSize= SvLEN(svBuf) - 1; \ } } STMT_END/* Grow a buffer where we have its size in WCHARs: */#define grow_buf_lw( swBuf,svBuf, lwSize,svSize ) STMT_START { \ if( null_arg(svBuf) ) { \ swBuf= NULL; \ } else { \ STRLEN n_a; \ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ (void) SvPV_force( svBuf, n_a ); \ swBuf= lwSvGROW( svBuf, lwSize ); \ if( autosize(svSize) ) \ lwSize= SvLEN(svBuf)/sizeof(WCHAR) - 1; \ } } STMT_END/* Grow a buffer that contains the declared fixed data type: */#define grow_buf( pBuf,svBuf, tpBuf ) STMT_START { \ if( null_arg(svBuf) ) { \ pBuf= NULL; \ } else { \ STRLEN n_a; \ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ (void) SvPV_force( svBuf, n_a ); \ pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(*pBuf) ) ); \ } } STMT_END/* Grow a buffer that contains a fixed data type other than that declared: */#define grow_buf_typ( pBuf,svBuf,tpBuf, Type ) STMT_START { \ if( null_arg(svBuf) ) { \ pBuf= NULL; \ } else { \ STRLEN n_a; \ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ (void) SvPV_force( svBuf, n_a ); \ pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(Type) ) ); \ } } STMT_END/* Grow a buffer that contains a list of items of the declared data type: */#define grow_vect( pBuf,svBuf,tpBuf, cItems ) STMT_START { \ if( null_arg(svBuf) ) { \ pBuf= NULL; \ } else { \ STRLEN n_a; \ if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ (void) SvPV_force( svBuf, n_a ); \ pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(*pBuf)*cItems ) ); \ } } STMT_END/* If call succeeded, set data length to returned length (in bytes): */#define trunc_buf_l( bOkay, sBuf,svBuf, lSize ) STMT_START { \ if( bOkay && NULL != sBuf ) { \ SvPOK_only( svBuf ); \ SvCUR_set( svBuf, lSize ); \ } } STMT_END/* Same as above except we have a poitner to the returned length: */#define trunc_buf_pl( bOkay, sBuf,svBuf, plSize ) \ trunc_buf_l( bOkay, sBuf,svBuf, *plSize )/* If call succeeded, set data length to returned length (in WCHARs): */#define trunc_buf_lw( bOkay, sBuf,svBuf, lwSize ) STMT_START { \ if( bOkay && NULL != sBuf ) { \ SvPOK_only( svBuf ); \ SvCUR_set( svBuf, (lwSize)*sizeof(WCHAR) ); \ } } STMT_END/* Same as above except we have a poitner to the returned length: */#define trunc_buf_plw( bOkay, swBuf,svBuf, plwSize ) \ trunc_buf_lw( bOkay, swBuf,svBuf, *plwSize )/* Set data length for a buffer that contains the declared fixed data type: */#define trunc_buf( bOkay, pBuf,svBuf ) STMT_START { \ if( bOkay && NULL != pBuf ) { \ SvPOK_only( svBuf ); \ SvCUR_set( svBuf, sizeof(*pBuf) ); \ } } STMT_END/* Set data length for a buffer that contains some other fixed data type: */#define trunc_buf_typ( bOkay, pBuf,svBuf, Type ) STMT_START { \ if( bOkay && NULL != pBuf ) { \ SvPOK_only( svBuf ); \ SvCUR_set( svBuf, sizeof(Type) ); \ } } STMT_END/* Set length for buffer that contains list of items of the declared type: */#define trunc_vect( bOkay, pBuf,svBuf, cItems ) STMT_START { \ if( bOkay && NULL != pBuf ) { \ SvPOK_only( svBuf ); \ SvCUR_set( svBuf, sizeof(*pBuf)*cItems ); \ } } STMT_END/* Set data length for a buffer where a '\0'-terminate string was stored: */#define trunc_buf_z( bOkay, sBuf,svBuf ) STMT_START { \ if( bOkay && NULL != sBuf ) { \ SvPOK_only( svBuf ); \ SvCUR_set( svBuf, strlen(sBuf) ); \ } } STMT_END/* Set data length for a buffer where a L'\0'-terminate string was stored: */#define trunc_buf_zw( bOkay, sBuf,svBuf ) STMT_START { \ if( bOkay && NULL != sBuf ) { \ SvPOK_only( svBuf ); \ SvCUR_set( svBuf, wcslen(sBuf)*sizeof(WCHAR) ); \ } } STMT_END
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -