]> git.saurik.com Git - apple/security.git/blob - SecuritySNACCRuntime/c-lib/src/sbuf.c
Security-54.1.tar.gz
[apple/security.git] / SecuritySNACCRuntime / c-lib / src / sbuf.c
1 /*
2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /*
20 * .../c-lib/src/sbuf.c
21 *
22 * Copyright (C) 1992 Michael Sample and the University of British Columbia
23 * MS
24 * This library is free software; you can redistribute it and/or
25 * modify it provided that this copyright/license information is retained
26 * in original form.
27 *
28 * If you modify this file, you must clearly indicate your changes.
29 *
30 * This source code is distributed in the hope that it will be
31 * useful, but WITHOUT ANY WARRANTY; without even the implied warranty
32 * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
33 */
34
35 #ifdef USE_GEN_BUF
36
37 #include "asn-config.h"
38 #include "gen-buf.h"
39 #include "sbuf.h"
40
41 /*
42 * casts are used to overcome void * - SBuf * conflict
43 * be careful if you modify param lists etc.
44 */
45 static struct GenBuf sBufOpsG =
46 {
47 (BufGetByteFcn) SBufGetByte,
48 (BufGetSegFcn) SBufGetSeg,
49 (BufCopyFcn) SBufCopy,
50 (BufSkipFcn) SBufSkip,
51 (BufPeekByteFcn) SBufPeekByte,
52 (BufPeekSegFcn) SBufPeekSeg,
53 (BufPeekCopyFcn) SBufPeekCopy,
54 (BufPutByteRvsFcn) SBufPutByteRvs,
55 (BufPutSegRvsFcn) SBufPutSegRvs,
56 (BufReadErrorFcn) SBufReadError,
57 (BufWriteErrorFcn) SBufWriteError,
58 NULL,
59 NULL
60 };
61
62 void
63 PutSBufInGenBuf PARAMS ((sb, gb),
64 SBuf *sb _AND_
65 GenBuf *gb)
66 {
67 *gb = sBufOpsG; /* structure assignemnt */
68 gb->bufInfo = sb;
69 }
70
71 /*
72 * given an SBuf,b, and a block of data
73 * and its length this initializes a the SBuf
74 * to point to the data block. The data
75 * block is assumed to contain no valid data-
76 * ie it is empty and ready for writing
77 */
78 void
79 SBufInit PARAMS ((b, data, dataLen),
80 SBuf *b _AND_
81 char *data _AND_
82 long int dataLen)
83 {
84 b->readError = b->writeError = 1;
85 b->blkStart = data;
86 b->blkEnd = data + dataLen;
87 b->dataStart = b->dataEnd = b->readLoc = b->blkEnd;
88 } /* SBufInit */
89
90
91 /*
92 * puts the given buffer in read mode and sets
93 * the current read location to the beginning of
94 * the buffer's data.
95 * The read error flag is cleared.
96 * The writeError flag is set so that attempted writes
97 * will be fail and be detectable via a call to
98 * SBufWriteError().
99 */
100 void
101 SBufResetInReadMode PARAMS ((b),
102 SBuf *b)
103 {
104 b->readLoc = b->dataStart;
105 b->readError = 0;
106 b->writeError = 1;
107 } /* SBufResetInnReadMode */
108
109
110 /*
111 * puts the given buffer in reverse writing mode and sets
112 * the current write location to the end of the
113 * buffer's data block.
114 * The data start and end pointers are set to point to
115 * the end of the block - ie no data.
116 * The write error flag is cleared.
117 * The readError flag is set so that attempted reads
118 * will be fail and be detectable via a call to
119 * SBufReadError().
120 */
121 void
122 SBufResetInWriteRvsMode PARAMS ((b),
123 SBuf *b)
124 {
125 b->dataStart = b->dataEnd = b->blkEnd;
126 b->writeError = 0;
127 b->readError = 1;
128 } /* SBufResetInWriteRvsMode */
129
130 /*
131 * installs given block of data into a buffer
132 * and sets it up for reading
133 */
134 void
135 SBufInstallData PARAMS ((b, data, dataLen),
136 SBuf *b _AND_
137 char *data _AND_
138 long int dataLen)
139 {
140 SBufInit (b, data, dataLen);
141 b->dataStart = b->blkStart;
142 SBufResetInReadMode (b);
143 } /* SBufInstallData */
144
145 /*
146 * returns the number of bytes in the data portion
147 */
148 long int
149 SBufDataLen PARAMS ((b),
150 SBuf *b)
151 {
152 return b->dataEnd - b->dataStart;
153 } /* SBufDataLen */
154
155 /*
156 * returns the pointer to the first data byte
157 */
158 char*
159 SBufDataPtr PARAMS ((b),
160 SBuf *b)
161 {
162 b->dataStart;
163 } /* SBufDataPtr */
164
165 /*
166 * returns the size of block, the maximum size for data
167 * (does not look at how much data is present, just the
168 * max size if the block were empty)
169 */
170 long int
171 SBufBlkLen PARAMS ((b),
172 SBuf *b)
173 {
174 return b->blkEnd - b->blkStart;
175 } /* SBufBlkLen */
176
177 /*
178 * returns a pointer to the first byte of the block
179 */
180 char*
181 SBufBlkPtr PARAMS ((b),
182 SBuf *b)
183 {
184 return b->blkStart;
185 } /* SBufBlkPtr */
186
187 /*
188 * returns true if there is no more data
189 * to be read in the SBuf
190 */
191 int
192 SBufEod PARAMS ((b),
193 SBuf *b)
194 {
195 return b->readLoc >= b->dataEnd;
196 } /* SBufEod */
197
198
199 /* returns true if you attempted to read past the end of data */
200 int
201 SBufReadError PARAMS ((b),
202 SBuf *b)
203 {
204 return b->readError;
205 } /* SBufReadError */
206
207 /*
208 * returns true if you attempted to write past the end of the block
209 * (remember SBufs do not expand like ExpBufs)
210 */
211 int
212 SBufWriteError PARAMS ((b),
213 SBuf *b)
214 {
215 return b->writeError;
216 } /* SBufWriteError */
217
218 /*
219 * Skips the next skipLen bytes for reading
220 */
221 void
222 SBufSkip PARAMS ((b, skipLen),
223 SBuf *b _AND_
224 long int skipLen)
225 {
226 if (b->readLoc + skipLen > b->dataEnd)
227 {
228 b->readLoc = b->dataEnd;
229 b->readError = 1;
230 }
231 else
232 b->readLoc += skipLen;
233 } /* SBufSkip */
234
235
236 /*
237 * copies copyLen bytes from buffer b into char *dst.
238 * Advances the curr read loc by copyLen
239 * Assumes dst is pre-allocated and is large enough.
240 * Will set the read error flag is you attempt to copy
241 * more than the number of unread bytes available.
242 */
243 void
244 SBufCopy PARAMS ((dst, b, copyLen),
245 char *dst _AND_
246 SBuf *b _AND_
247 long int copyLen)
248 {
249 if (b->readLoc + copyLen > b->dataEnd)
250 {
251 memcpy (dst, b->readLoc, b->dataEnd - b->readLoc);
252 b->readLoc = b->dataEnd;
253 b->readError = 1;
254 }
255 else
256 {
257 memcpy (dst, b->readLoc, copyLen);
258 b->readLoc += copyLen;
259 }
260 } /* SBufCopy */
261
262
263 /*
264 * returns the next byte from the buffer without advancing the
265 * current read location.
266 */
267 unsigned char
268 SBufPeekByte PARAMS ((b),
269 SBuf *b)
270 {
271 if (SBufEod (b))
272 {
273 b->readError = 1;
274 return (unsigned char)0;
275 }
276 else
277 return (unsigned char) *b->readLoc;
278 } /* SBufPeekByte */
279
280 #if TTBL
281
282 /*
283 * returns a pointer into the buffer to the next bytes to be read.
284 * If *lenPtr unread bytes are not available, *lenPtr will be set
285 * to the number of bytes that are available. The current read location
286 * is *NOT* advanced at all. The read error flag will NOT be set
287 * by this routine.
288 */
289 char*
290 SBufPeekSeg PARAMS ((b, lenPtr),
291 SBuf *b _AND_
292 long int *lenPtr)
293 {
294 if (b->readLoc + *lenPtr > b->dataEnd)
295 *lenPtr = b->dataEnd - b->readLoc;
296
297 return b->readLoc;
298 } /* SBufPeekSeg */
299
300
301
302 /*
303 * copies copyLen bytes from buffer b into char *dst.
304 * Does NOT advance the curr read location.
305 * assumes dst is pre-allocated and is large enough.
306 * Will set the read error flag is you attempt to copy
307 * more than the number of unread bytes available.
308 */
309 void
310 SBufPeekCopy PARAMS ((dst, b, copyLen),
311 char *dst _AND_
312 SBuf *b _AND_
313 long int copyLen)
314 {
315 if (b->readLoc + copyLen > b->dataEnd)
316 {
317 memcpy (dst, b->readLoc, b->dataEnd - b->readLoc);
318 b->readError = 1;
319 }
320 else
321 memcpy (dst, b->readLoc, copyLen);
322
323 } /* SBufCopy */
324
325 #endif /* TTBL */
326
327 /*
328 * returns a pointer into the buffer to the next bytes to be read.
329 * If *lenPtr unread bytes are not available, *lenPtr will be set
330 * to the number of bytes that are available. The current read location
331 * is advance by the number of bytes returned in *lenPtr. The read error
332 * flag will NOT be set, ever, by this routine.
333 */
334 char*
335 SBufGetSeg PARAMS ((b, lenPtr),
336 SBuf *b _AND_
337 long int *lenPtr)
338 {
339 char *retVal;
340 retVal = b->readLoc;
341
342 if (b->readLoc + *lenPtr > b->dataEnd)
343 {
344 *lenPtr = b->dataEnd - b->readLoc;
345 b->readLoc = b->dataEnd;
346 }
347 else
348 b->readLoc += *lenPtr;
349
350 return retVal;
351 } /* SBufGetSeg */
352
353 /*
354 * Write in reverse the char *seg of segLen bytes to the buffer b.
355 * A reverse write of segement really just prepends the given seg
356 * (in original order) to the buffers existing data.
357 * If the SBuf does not have enough room for the segment,
358 * the writeError flag is set and *NO* copying is done at all.
359 */
360 void
361 SBufPutSegRvs PARAMS ((b, seg, segLen),
362 SBuf *b _AND_
363 char *seg _AND_
364 long int segLen)
365 {
366 if (b->dataStart - segLen < b->blkStart)
367 b->writeError = 1;
368 else
369 {
370 b->dataStart -= segLen;
371 memcpy (b->dataStart, seg, segLen);
372 }
373 } /* SBufPutSegRvs */
374
375 /*
376 * returns the next byte from buffer b's data and advances the
377 * current read location by one byte. This will set the read error
378 * flag if you attempt to read past the end of the SBuf
379 */
380 unsigned char
381 SBufGetByte PARAMS ((b),
382 SBuf *b)
383 {
384 if (SBufEod (b))
385 b->readError = 1;
386 else
387 return (unsigned char)(*(b->readLoc++));
388 } /* SBufGetByte */
389
390
391 /*
392 * writes (prepends) the given byte to buffer b's data
393 */
394 void
395 SBufPutByteRvs PARAMS ((b, byte),
396 SBuf *b _AND_
397 unsigned char byte)
398 {
399 if (b->dataStart <= b->blkStart)
400 b->writeError = 1;
401 else
402 *--b->dataStart = byte;
403 } /* SBufPutByteRvs */
404
405 #endif /* USE_GEN_BUF */