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