1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd">
<HTML
><HEAD
><TITLE
>Preparing PDUs</TITLE
><META
NAME="GENERATOR"
CONTENT="Modular DocBook HTML Stylesheet Version 1.79"><LINK
REL="HOME"
TITLE="YAZ User's Guide and Reference"
HREF="yaz.html"><LINK
REL="UP"
TITLE="The Z39.50 ASN.1 Module"
HREF="asn.html"><LINK
REL="PREVIOUS"
TITLE="The Z39.50 ASN.1 Module"
HREF="asn.html"><LINK
REL="NEXT"
TITLE="Object Identifiers"
HREF="asn.oid.html"><LINK
REL="STYLESHEET"
TYPE="text/css"
HREF="common/style1.css"></HEAD
><BODY
CLASS="sect1"
BGCOLOR="#FFFFFF"
TEXT="#000000"
LINK="#0000FF"
VLINK="#840084"
ALINK="#0000FF"
><DIV
CLASS="NAVHEADER"
><TABLE
SUMMARY="Header navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TH
COLSPAN="3"
ALIGN="center"
>YAZ User's Guide and Reference</TH
></TR
><TR
><TD
WIDTH="10%"
ALIGN="left"
VALIGN="bottom"
><A
HREF="asn.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="80%"
ALIGN="center"
VALIGN="bottom"
>Chapter 6. The Z39.50 ASN.1 Module</TD
><TD
WIDTH="10%"
ALIGN="right"
VALIGN="bottom"
><A
HREF="asn.oid.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
></TABLE
><HR
ALIGN="LEFT"
WIDTH="100%"></DIV
><DIV
CLASS="sect1"
><H1
CLASS="sect1"
><A
NAME="asn.preparing"
>Preparing PDUs</A
></H1
><P
> A structure representing a complex ASN.1 type doesn't in itself contain the
members of that type. Instead, the structure contains
<SPAN
CLASS="emphasis"
><I
CLASS="emphasis"
>pointers</I
></SPAN
> to the members of the type.
This is necessary, in part, to allow a mechanism for specifying which
of the optional structure (SEQUENCE) members are present, and which
are not. It follows that you will need to somehow provide space for
the individual members of the structure, and set the pointers to
refer to the members.
</P
><P
> The conversion routines don't care how you allocate and maintain your
C structures - they just follow the pointers that you provide.
Depending on the complexity of your application, and your personal
taste, there are at least three different approaches that you may take
when you allocate the structures.
</P
><P
> You can use static or automatic local variables in the function that
prepares the PDU. This is a simple approach, and it provides the most
efficient form of memory management. While it works well for flat
PDUs like the InitReqest, it will generally not be sufficient for say,
the generation of an arbitrarily complex RPN query structure.
</P
><P
> You can individually create the structure and its members using the
<CODE
CLASS="function"
>malloc(2)</CODE
> function. If you want to ensure that
the data is freed when it is no longer needed, you will have to
define a function that individually releases each member of a
structure before freeing the structure itself.
</P
><P
> You can use the <CODE
CLASS="function"
>odr_malloc()</CODE
> function (see
<A
HREF="odr.use.html"
>the Section called <I
>Using ODR</I
> in Chapter 9</A
> for details). When you use
<CODE
CLASS="function"
>odr_malloc()</CODE
>, you can release all of the
allocated data in a single operation, independent of any pointers and
relations between the data. <CODE
CLASS="function"
>odr_malloc()</CODE
> is based on a
"nibble-memory"
scheme, in which large portions of memory are allocated, and then
gradually handed out with each call to <CODE
CLASS="function"
>odr_malloc()</CODE
>.
The next time you call <CODE
CLASS="function"
>odr_reset()</CODE
>, all of the
memory allocated since the last call is recycled for future use (actually,
it is placed on a free-list).
</P
><P
> You can combine all of the methods described here. This will often be
the most practical approach. For instance, you might use
<CODE
CLASS="function"
>odr_malloc()</CODE
> to allocate an entire structure and
some of its elements, while you leave other elements pointing to global
or per-session default variables.
</P
><P
> The Z39.50 ASN.1 module provides an important aid in creating new PDUs. For
each of the PDU types (say, <CODE
CLASS="function"
>Z_InitRequest</CODE
>), a
function is provided that allocates and initializes an instance of
that PDU type for you. In the case of the InitRequest, the function is
simply named <CODE
CLASS="function"
>zget_InitRequest()</CODE
>, and it sets up
reasonable default value for all of the mandatory members. The optional
members are generally initialized to null pointers. This last aspect
is very important: it ensures that if the PDU definitions are
extended after you finish your implementation (to accommodate
new versions of the protocol, say), you won't get into trouble with
uninitialized pointers in your structures. The functions use
<CODE
CLASS="function"
>odr_malloc()</CODE
> to
allocate the PDUs and its members, so you can free everything again with a
single call to <CODE
CLASS="function"
>odr_reset()</CODE
>. We strongly recommend
that you use the <TT
CLASS="literal"
>zget_*</TT
>
functions whenever you are preparing a PDU (in a C++ API, the
<TT
CLASS="literal"
>zget_</TT
>
functions would probably be promoted to constructors for the
individual types).
</P
><P
> The prototype for the individual PDU types generally look like this:
</P
><PRE
CLASS="synopsis"
> Z_<type> *zget_<type>(ODR o);
</PRE
><P
> eg.:
</P
><PRE
CLASS="synopsis"
> Z_InitRequest *zget_InitRequest(ODR o);
</PRE
><P
> The <ACRONYM
CLASS="acronym"
>ODR</ACRONYM
> handle should generally be your encoding stream, but it
needn't be.
</P
><P
> As well as the individual PDU functions, a function
<CODE
CLASS="function"
>zget_APDU()</CODE
> is provided, which allocates
a top-level Z-APDU of the type requested:
</P
><PRE
CLASS="synopsis"
> Z_APDU *zget_APDU(ODR o, int which);
</PRE
><P
> The <CODE
CLASS="varname"
>which</CODE
> parameter is (of course) the discriminator
belonging to the <CODE
CLASS="varname"
>Z_APDU</CODE
> <TT
CLASS="literal"
>CHOICE</TT
> type.
All of the interface described here is provided by the Z39.50 ASN.1 module, and
you access it through the <TT
CLASS="filename"
>proto.h</TT
> header file.
</P
></DIV
><DIV
CLASS="NAVFOOTER"
><HR
ALIGN="LEFT"
WIDTH="100%"><TABLE
SUMMARY="Footer navigation table"
WIDTH="100%"
BORDER="0"
CELLPADDING="0"
CELLSPACING="0"
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
><A
HREF="asn.html"
ACCESSKEY="P"
>Prev</A
></TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="yaz.html"
ACCESSKEY="H"
>Home</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
><A
HREF="asn.oid.html"
ACCESSKEY="N"
>Next</A
></TD
></TR
><TR
><TD
WIDTH="33%"
ALIGN="left"
VALIGN="top"
>The Z39.50 ASN.1 Module</TD
><TD
WIDTH="34%"
ALIGN="center"
VALIGN="top"
><A
HREF="asn.html"
ACCESSKEY="U"
>Up</A
></TD
><TD
WIDTH="33%"
ALIGN="right"
VALIGN="top"
>Object Identifiers</TD
></TR
></TABLE
></DIV
></BODY
></HTML
>
|