1 /* buffers.h -- Version 1.11 */ 2 3 /* The following abbreviations are used at start of parameter names 4 * to indicate the type of data: 5 * s string (char * or WCHAR *) [PV] 6 * sw wide string (WCHAR *) [PV] 7 * p pointer (usually to some structure) [PV] 8 * a array (packed array as in C) (usually of some structure) [PV] 9 * called a "vector" or "vect" in some places. 10 * n generic number [IV, UV, or NV] 11 * iv signed integral value [IV] 12 * u unsigned integral value [UV] 13 * d floating-point number (double) [NV] 14 * b boolean (bool) [IV] 15 * c count of items [UV] 16 * l length (in bytes) [UV] 17 * lw length in WCHARs [UV] 18 * h a handle [IV] 19 * r record (structure) [PV] 20 * sv Perl scalar (s, i, u, d, n, or rv) [SV] 21 * rv Perl reference (usually to scalar) [RV] 22 * hv reference to Perl hash [HV] 23 * av reference to Perl array [AV] 24 * cv Perl code reference [PVCV] 25 * 26 * Unusual combined types: 27 * pp single pointer (to non-Perl data) packed into string [PV] 28 * pap vector of pointers (to non-Perl data) packed into string [PV] 29 * 30 * Whether a parameter is for input data, output data, or both is usually 31 * not reflected by the data type prefix. In cases where this is not 32 * obvious nor reflected in the variable name proper, you can use 33 * the following in front of the data type prefix: 34 * i an input parameter given to API (usually omitted) 35 * o an Output parameter taken from API 36 * io Input given to API then overwritten with Output taken from API 37 */ 38 39 /* Buffer arguments are usually followed by an argument (or two) specifying 40 * their size and/or returning the size of data written. The size can be 41 * measured in bytes ["lSize"] or in characters [for (char *) buffers such as 42 * for *A() routines, these sizes are also called "lSize", but are called 43 * "lwSize" for (WCHAR *) buffers, UNICODE strings, such as for *W() routines]. 44 * 45 * Before calling the actual C function, you must make sure the Perl variable 46 * actually has a big enough buffer allocated, and, if the user didn't want 47 * to specify a buffer size, set the buffer size to be correct. This is what 48 * the grow_*() macros are for. They also handle special meanings of the 49 * buffer size argument [described below]. 50 * 51 * Once the actual C function returns, you must set the Perl variable to know 52 * the size of the written data. This is what the trunc_*() macros are for. 53 * 54 * The size sometimes does and sometimes doesn't include the trailing '\0' 55 * [or L'\0'], so we always add or substract 1 in the appropriate places so 56 * we don't care about this detail. 57 * 58 * A call may 1) request a pointer to the buffer size which means that 59 * the buffer size will be overwritten with the size of the data written; 60 * 2) have an extra argument which is a pointer to the place to write the 61 * size of the written data; 3) provide the size of the written data in 62 * the function's return value; 4) format the data so that the length 63 * can be determined by examining the data [such as with '\0'-terminated 64 * strings]; or 5) write fixed-length data [usually sizeof(STRUCT)]. 65 * This obviously determines what you should use in the trunc_*() macro 66 # to specify the size of the output value. 67 * 68 * The user can pass in an empty list reference, C<[]>, to indicate C<NULL> 69 * for the pointer to the buffer which means that they don't want that data. 70 * 71 * The user can pass in C<[]> or C<0> to indicate that they don't care about 72 * the buffer size [we aren't programming in C here, after all] and just try 73 * to get the data. This will work if either the buffer already alloated for 74 * the SV [scalar value] is large enough to hold the data or the API provides 75 * an easy way to determine the required size [and the XS code uses it]. 76 * 77 * If the user passes in a numeric value for a buffer size, then the XS 78 * code makes sure that the buffer is at least large enough to hold a value 79 * of that size and then passes in how large the buffer is. So the buffer 80 * size passed to the API call is the larger of the size requested by the 81 * user and the size of the buffer aleady allocated to the SV. 82 * 83 * The user can also pass in a string consisting of a leading "=" followed 84 * by digits for a buffer size. This means just use the size specified after 85 * the equals sign, even if the allocated buffer is larger. The XS code will 86 * still allocate a large enough buffer before the first call. 87 * 88 * If the function is nice enough to tell us that a buffer was too small 89 * [usually via ERROR_MORE_DATA] _and_ how large the buffer needs to be, 90 * then the XS code should enlarge the buffer(s) and repeat the call [once]. 91 * This resizing is _not_ done for buffers whose size was specified with a 92 * leading "=". 93 * 94 * Only grow_buf() and perhaps trunc_buf() can be used in a typemap file. 95 * The other macros would be used in the parameter declarations or INPUT: 96 * section [grow_*()], the INIT: section [init_*()], or the OUTPUT: section 97 * [trunc_*()]. 98 * 99 * Buffer arguments should be initialied with C<= NO_INIT> [or C<= NULL;>]. 100 * 101 * See also the F<typemap> file. C<oDWORD>, for example, is for an output- 102 * only parameter of type C<DWORD> and you should simply C<#define> it to be 103 * C<DWORD>. In F<typemap>, C<oDWORD> is treated differently than C<DWORD> 104 * in two ways. 105 * 106 * First, if C<undef> is passed in, a C<DWORD> could generate a warning 107 * when it gets converted to 0 while C<oDWORD> will never generate such a 108 * warning for C<undef>. This first difference doesn't apply if specific 109 * initialization is specified for the variable, as in C<= init_buf_l($var);>. 110 * In particular, the init_*() macros also convert C<undef> to 0 without 111 * ever producing a warning. 112 * 113 * Second, passing in a read-only SV for a C<oDWORD> parameter will generate 114 * a fatal error on output when we try to update the SV. For C<DWORD>, we 115 * won't update a read-only SV since passing in a literal constant for a 116 * buffer size is a useful thing to do even though it prevents us from 117 * returning the size of data written via that SV. Since we should use a 118 * trunc_*() macro to output the actual data, the user should be able to 119 * determine the size of data written based on the size of the scalar we 120 * output anyway. 121 * 122 * This second difference doesn't apply unless the paremter is listed in 123 * the OUTPUT: section without specific output instructions. We define 124 * no macros for outputing buffer length parameters so be careful to use 125 * C<oDWORD> [for example] for them if and only if they are output-only. 126 * 127 * Note that C<oDWORD> is the same as C<DWORD> in that, if a defined value 128 * is passed in, it is used [and can generate a warning if the value is 129 * "not numeric"]. So although C<oDWORD> is for output-only parameters, 130 * we still initialize the C variable before calling the API. This is good 131 * in case the parameter isn't always strictly output-only due to upgrades, 132 * bugs, etc. 133 * 134 * Here is a made-up example that shows several cases: 135 * 136 * # Actual GetDataW() returns length of data written to ioswName, not bool. 137 * bool 138 * GetDataW( ioswName, ilwName, oswText, iolwText, opJunk, opRec, ilRec, olRec ) 139 * WCHAR * ioswName = NO_INIT 140 * DWORD ilwName = NO_INIT 141 * WCHAR * oswText = NO_INIT 142 * DWORD &iolwText = init_buf_l($arg); 143 * void * opJunk = NO_INIT 144 * BYTE * opRec = NO_INIT 145 * DWORD ilRec = init_buf_l($arg); 146 * oDWORD &olRec 147 * PREINIT: 148 * DWORD olwName; 149 * INIT: 150 * grow_buf_lw( ioswName,ST(0), ilwName,ST(1) ); 151 * grow_buf_lw( oswText,ST(2), iolwText,ST(3) ); 152 * grow_buf_typ( opJunk,ST(4),void *, LONG_STRUCT_TYPEDEF ); 153 * grow_buf_l( opRec,ST(5),BYTE *, ilRec,ST(6) ); 154 * CODE: 155 * olwName= GetDataW( ioswName, ilwName, oswText, &iolwText, 156 * (LONG_STRUCT_TYPEDEF *)opJunk, opRec, &iolRec ); 157 * if( 0 == olwName && ERROR_MORE_DATA == GetLastError() 158 * && ( autosize(ST(1)) || autosize(ST(3)) || autosize(ST(6)) ) ) { 159 * if( autosize(ST(1)) ) 160 * grow_buf_lw( ioswName,ST(0), ilwName,ST(1) ); 161 * if( autosize(ST(3)) ) 162 * grow_buf_lw( oswText,ST(2), iolwText,ST(3) ); 163 * if( autosize(ST(6)) ) 164 * grow_buf_l( opRec,ST(5),BYTE *, iolRec,ST(6) ); 165 * olwName= GetDataW( ioswName, ilwName, oswText, &iolwText, 166 * (LONG_STRUCT_TYPEDEF *)opJunk, opRec, &iolRec ); 167 * } 168 * RETVAL= 0 != olwName; 169 * OUTPUT: 170 * RETVAL 171 * ioswName trunc_buf_lw( RETVAL, ioswName,ST(0), olwName ); 172 * oswText trunc_buf_lw( RETVAL, oswText,ST(2), iolwText ); 173 * iolwText 174 * opJunk trunc_buf_typ(RETVAL,opJunk,ST(4),LONG_STRUCT_TYPEDEF); 175 * opRec trunc_buf_l( RETVAL, opRec,ST(5), olRec ); 176 * olRec 177 * 178 * The above example would be more complex and less efficient if we used 179 * C<DWORD * iolwText> in place of C<DWORD &iolwText>. The only possible 180 * advantage would be that C<NULL> would be passed in for C<iolwText> if 181 * _both_ C<$oswText> and C<$iolwText> were specified as C<[]>. The *_pl*() 182 * macros are defined [and C<DWORD *> specified in F<typemap>] so we can 183 * handle those cases but it is usually better to use the *_l*() macros 184 * instead by specifying C<&> instead of C<*>. Using C<&> instead of C<*> 185 * is usually better when dealing with scalars, even if they aren't buffer 186 * sizes. But you must use C<*> if it is important for that parameter to 187 * be able to pass C<NULL> to the underlying API. 188 * 189 * In Win32API::, we try to use C<*> for buffer sizes of optional buffers 190 * and C<&> for buffer sizes of required buffers. 191 * 192 * For parameters that are pointers to things other than buffers or buffer 193 * sizes, we use C<*> for "important" parameters [so that using C<[]> 194 * generates an error rather than fetching the value and just throwing it 195 * away], and for optional parameters [in case specifying C<NULL> is or 196 * becomes important]. Otherwise we use C<&> [for "unimportant" but 197 * required parameters] so the user can specify C<[]> if they don't care 198 * about it. The output handle of an "open" routine is "important". 199 */ 200 201 #ifndef Debug 202 # define Debug(list) /*Nothing*/ 203 #endif 204 205 /*#ifndef CAST 206 *# ifdef __cplusplus 207 *# define CAST(type,expr) static_cast<type>(expr) 208 *# else*/ 209 # define CAST(type,expr) (type)(expr) 210 /*# endif 211 *#endif*/ 212 213 /* Is an argument C<[]>, meaning we should pass C<NULL>? */ 214 #define null_arg(sv) ( SvROK(sv) && SVt_PVAV == SvTYPE(SvRV(sv)) \ 215 && -1 == av_len((AV*)SvRV(sv)) ) 216 217 #define PV_or_null(sv) ( null_arg(sv) ? NULL : SvPV_nolen(sv) ) 218 219 /* Minimum buffer size to use when no buffer existed: */ 220 #define MIN_GROW_SIZE 128 221 222 #ifdef Debug 223 /* Used in Debug() messages to show which macro call is involved: */ 224 #define string(arg) #arg 225 #endif 226 227 /* Simplify using SvGROW() for byte-sized buffers: */ 228 #define lSvGROW(sv,n) SvGROW( sv, 0==(n) ? MIN_GROW_SIZE : (n)+1 ) 229 230 /* Simplify using SvGROW() for WCHAR-sized buffers: */ 231 #define lwSvGROW(sv,n) CAST( WCHAR *, \ 232 SvGROW( sv, sizeof(WCHAR)*( 0==(n) ? MIN_GROW_SIZE : (n)+1 ) ) ) 233 234 /* Whether the buffer size we got lets us change what buffer size we use: */ 235 #define autosize(sv) (!( SvOK(sv) && ! SvROK(sv) \ 236 && SvPV_nolen(sv) && '=' == *SvPV_nolen(sv) )) 237 238 /* Get the IV/UV for a parameter that might be C<[]> or C<undef>: */ 239 #define optIV(sv) ( null_arg(sv) ? 0 : !SvOK(sv) ? 0 : SvIV(sv) ) 240 #define optUV(sv) ( null_arg(sv) ? 0 : !SvOK(sv) ? 0 : SvUV(sv) ) 241 242 /* Allocate temporary storage that will automatically be freed later: */ 243 #ifndef TempAlloc /* Can be C<#define>d to be C<_alloca>, for example */ 244 # define TempAlloc( size ) sv_grow( sv_newmortal(), size ) 245 #endif 246 247 /* Initialize a buffer size argument of type (DWORD *): */ 248 #define init_buf_pl( plSize, svSize, tpSize ) STMT_START { \ 249 if( null_arg(svSize) ) \ 250 plSize= NULL; \ 251 else { \ 252 STRLEN n_a; \ 253 *( plSize= CAST( tpSize, TempAlloc(sizeof(*plSize)) ) )= \ 254 autosize(svSize) ? optUV(svSize) \ 255 : strtoul( 1+SvPV(svSize,n_a), NULL, 10 ); \ 256 } } STMT_END 257 /* In INPUT section put ": init_buf_pl($var,$arg,$type);" after var name. */ 258 259 /* Initialize a buffer size argument of type DWORD: */ 260 #define init_buf_l( svSize ) \ 261 ( null_arg(svSize) ? 0 : autosize(svSize) ? optUV(svSize) \ 262 : strtoul( 1+SvPV_nolen(svSize), NULL, 10 ) ) 263 /* In INPUT section put "= init_buf_l($arg);" after variable name. */ 264 265 /* Lengths in WCHARs are initialized the same as lengths in bytes: */ 266 #define init_buf_plw init_buf_pl 267 #define init_buf_lw init_buf_l 268 269 /* grow_buf_pl() and grow_buf_plw() are included so you can define 270 * parameters of type C<DWORD *>, for example. In practice, it is 271 * usually better to define such parameters as "DWORD &". */ 272 273 /* Grow a buffer where we have a pointer to its size in bytes: */ 274 #define grow_buf_pl( sBuf,svBuf,tpBuf, plSize,svSize,tpSize ) STMT_START { \ 275 Debug(("grow_buf_pl( %s==0x%lX,[%s:%ld/%ld, %s==0x%lX:%ld,[%s )\n",\ 276 string(sBuf),sBuf,strchr(string(svBuf),'('),SvPOK(svBuf)? \ 277 SvCUR(svBuf):-1,SvPOK(svBuf)?SvLEN(svBuf):-1,string(plSize), \ 278 plSize,plSize?*plSize:-1,strchr(string(svSize),'('))); \ 279 if( null_arg(svBuf) ) { \ 280 sBuf= NULL; \ 281 } else { \ 282 STRLEN n_a; \ 283 if( NULL == plSize ) \ 284 *( plSize= CAST(tpSize,TempAlloc(sizeof(*plSize))) )= 0;\ 285 if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ 286 (void) SvPV_force( svBuf, n_a ); \ 287 sBuf= CAST( tpBuf, lSvGROW( svBuf, *plSize ) ); \ 288 if( autosize(svSize) ) *plSize= SvLEN(svBuf) - 1; \ 289 Debug(("more buf_pl( %s==0x%lX,[%s:%ld/%ld, %s==0x%lX:%ld,[%s )\n",\ 290 string(sBuf),sBuf,strchr(string(svBuf),'('),SvPOK(svBuf)? \ 291 SvCUR(svBuf):-1,SvPOK(svBuf)?SvLEN(svBuf):-1,string(plSize),\ 292 plSize,plSize?*plSize:-1,strchr(string(svSize),'('))); \ 293 } } STMT_END 294 295 /* Grow a buffer where we have a pointer to its size in WCHARs: */ 296 #define grow_buf_plw( sBuf,svBuf, plwSize,svSize,tpSize ) STMT_START { \ 297 if( null_arg(svBuf) ) { \ 298 sBuf= NULL; \ 299 } else { \ 300 STRLEN n_a; \ 301 if( NULL == plwSize ) \ 302 *( plwSize= CAST(tpSize,TempAlloc(sizeof(*plwSize))) )= 0;\ 303 if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ 304 (void) SvPV_force( svBuf, n_a ); \ 305 sBuf= lwSvGROW( svBuf, *plwSize ); \ 306 if( autosize(svSize) ) \ 307 *plwSize= SvLEN(svBuf)/sizeof(WCHAR) - 1; \ 308 } } STMT_END 309 310 /* Grow a buffer where we have its size in bytes: */ 311 #define grow_buf_l( sBuf,svBuf,tpBuf, lSize,svSize ) STMT_START { \ 312 if( null_arg(svBuf) ) { \ 313 sBuf= NULL; \ 314 } else { \ 315 STRLEN n_a; \ 316 if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ 317 (void) SvPV_force( svBuf, n_a ); \ 318 sBuf= CAST( tpBuf, lSvGROW( svBuf, lSize ) ); \ 319 if( autosize(svSize) ) lSize= SvLEN(svBuf) - 1; \ 320 } } STMT_END 321 322 /* Grow a buffer where we have its size in WCHARs: */ 323 #define grow_buf_lw( swBuf,svBuf, lwSize,svSize ) STMT_START { \ 324 if( null_arg(svBuf) ) { \ 325 swBuf= NULL; \ 326 } else { \ 327 STRLEN n_a; \ 328 if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ 329 (void) SvPV_force( svBuf, n_a ); \ 330 swBuf= lwSvGROW( svBuf, lwSize ); \ 331 if( autosize(svSize) ) \ 332 lwSize= SvLEN(svBuf)/sizeof(WCHAR) - 1; \ 333 } } STMT_END 334 335 /* Grow a buffer that contains the declared fixed data type: */ 336 #define grow_buf( pBuf,svBuf, tpBuf ) STMT_START { \ 337 if( null_arg(svBuf) ) { \ 338 pBuf= NULL; \ 339 } else { \ 340 STRLEN n_a; \ 341 if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ 342 (void) SvPV_force( svBuf, n_a ); \ 343 pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(*pBuf) ) ); \ 344 } } STMT_END 345 346 /* Grow a buffer that contains a fixed data type other than that declared: */ 347 #define grow_buf_typ( pBuf,svBuf,tpBuf, Type ) STMT_START { \ 348 if( null_arg(svBuf) ) { \ 349 pBuf= NULL; \ 350 } else { \ 351 STRLEN n_a; \ 352 if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ 353 (void) SvPV_force( svBuf, n_a ); \ 354 pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(Type) ) ); \ 355 } } STMT_END 356 357 /* Grow a buffer that contains a list of items of the declared data type: */ 358 #define grow_vect( pBuf,svBuf,tpBuf, cItems ) STMT_START { \ 359 if( null_arg(svBuf) ) { \ 360 pBuf= NULL; \ 361 } else { \ 362 STRLEN n_a; \ 363 if( ! SvOK(svBuf) ) sv_setpvn(svBuf,"",0); \ 364 (void) SvPV_force( svBuf, n_a ); \ 365 pBuf= CAST( tpBuf, SvGROW( svBuf, sizeof(*pBuf)*cItems ) ); \ 366 } } STMT_END 367 368 /* If call succeeded, set data length to returned length (in bytes): */ 369 #define trunc_buf_l( bOkay, sBuf,svBuf, lSize ) STMT_START { \ 370 if( bOkay && NULL != sBuf ) { \ 371 SvPOK_only( svBuf ); \ 372 SvCUR_set( svBuf, lSize ); \ 373 } } STMT_END 374 375 /* Same as above except we have a poitner to the returned length: */ 376 #define trunc_buf_pl( bOkay, sBuf,svBuf, plSize ) \ 377 trunc_buf_l( bOkay, sBuf,svBuf, *plSize ) 378 379 /* If call succeeded, set data length to returned length (in WCHARs): */ 380 #define trunc_buf_lw( bOkay, sBuf,svBuf, lwSize ) STMT_START { \ 381 if( bOkay && NULL != sBuf ) { \ 382 SvPOK_only( svBuf ); \ 383 SvCUR_set( svBuf, (lwSize)*sizeof(WCHAR) ); \ 384 } } STMT_END 385 386 /* Same as above except we have a poitner to the returned length: */ 387 #define trunc_buf_plw( bOkay, swBuf,svBuf, plwSize ) \ 388 trunc_buf_lw( bOkay, swBuf,svBuf, *plwSize ) 389 390 /* Set data length for a buffer that contains the declared fixed data type: */ 391 #define trunc_buf( bOkay, pBuf,svBuf ) STMT_START { \ 392 if( bOkay && NULL != pBuf ) { \ 393 SvPOK_only( svBuf ); \ 394 SvCUR_set( svBuf, sizeof(*pBuf) ); \ 395 } } STMT_END 396 397 /* Set data length for a buffer that contains some other fixed data type: */ 398 #define trunc_buf_typ( bOkay, pBuf,svBuf, Type ) STMT_START { \ 399 if( bOkay && NULL != pBuf ) { \ 400 SvPOK_only( svBuf ); \ 401 SvCUR_set( svBuf, sizeof(Type) ); \ 402 } } STMT_END 403 404 /* Set length for buffer that contains list of items of the declared type: */ 405 #define trunc_vect( bOkay, pBuf,svBuf, cItems ) STMT_START { \ 406 if( bOkay && NULL != pBuf ) { \ 407 SvPOK_only( svBuf ); \ 408 SvCUR_set( svBuf, sizeof(*pBuf)*cItems ); \ 409 } } STMT_END 410 411 /* Set data length for a buffer where a '\0'-terminate string was stored: */ 412 #define trunc_buf_z( bOkay, sBuf,svBuf ) STMT_START { \ 413 if( bOkay && NULL != sBuf ) { \ 414 SvPOK_only( svBuf ); \ 415 SvCUR_set( svBuf, strlen(sBuf) ); \ 416 } } STMT_END 417 418 /* Set data length for a buffer where a L'\0'-terminate string was stored: */ 419 #define trunc_buf_zw( bOkay, sBuf,svBuf ) STMT_START { \ 420 if( bOkay && NULL != sBuf ) { \ 421 SvPOK_only( svBuf ); \ 422 SvCUR_set( svBuf, wcslen(sBuf)*sizeof(WCHAR) ); \ 423 } } STMT_END 424