NCBI C Toolkit Cross Reference

C/corelib/ncbibs.c


  1 /*  ncbibs.c
  2 * ===========================================================================
  3 *
  4 *                            PUBLIC DOMAIN NOTICE                          
  5 *               National Center for Biotechnology Information
  6 *                                                                          
  7 *  This software/database is a "United States Government Work" under the   
  8 *  terms of the United States Copyright Act.  It was written as part of    
  9 *  the author's official duties as a United States Government employee and 
 10 *  thus cannot be copyrighted.  This software/database is freely available 
 11 *  to the public for use. The National Library of Medicine and the U.S.    
 12 *  Government have not placed any restriction on its use or reproduction.  
 13 *                                                                          
 14 *  Although all reasonable efforts have been taken to ensure the accuracy  
 15 *  and reliability of the software and data, the NLM and the U.S.          
 16 *  Government do not and cannot warrant the performance or results that    
 17 *  may be obtained by using this software or data. The NLM and the U.S.    
 18 *  Government disclaim all warranties, express or implied, including       
 19 *  warranties of performance, merchantability or fitness for any particular
 20 *  purpose.                                                                
 21 *                                                                          
 22 *  Please cite the author in any work or product based on this material.   
 23 *
 24 * ===========================================================================
 25 *
 26 * File Name:  ncbibs.c
 27 *
 28 * Author:  Jim Ostell
 29 *
 30 * Version Creation Date:  3/4/91
 31 *
 32 * $Revision: 6.8 $
 33 *
 34 * File Description:
 35 *   ByteStore functions
 36 *      NOTE: increasing BS_MAXALLOC will require changing len, and
 37 *                  len_avail to Int4 (ncbibs.h)
 38 *
 39 *   This version needs the following enhancements:
 40 *   1) a BSCompact function to pack a fragmented ByteStore
 41 *   2) use made of MIN_BSALLOC to make all allocated space at
 42 *      least MIN_BSALLOC long, so it would be possible to have len_avail
 43 *      bigger than len at internal BSUnits as well as at the end.  This
 44 *      will make insertion and appending of small amounts much more
 45 *      efficient.
 46 *
 47 * Modifications:  
 48 * --------------------------------------------------------------------------
 49 * Date     Name        Description of modification
 50 * -------  ----------  -----------------------------------------------------
 51 *
 52 * ==========================================================================
 53 */
 54 
 55 #include <ncbi.h>
 56 #include <ncbiwin.h>
 57 
 58          /* maximum size allocated for BSUnit.str */
 59 #define MAX_BSALLOC 32700
 60          /* minimum size block to allocate except on new */
 61 #define MIN_BSALLOC 1024
 62 
 63 #ifdef MSC_VIRT
 64 extern Nlm_Boolean wrote_to_handle;  /* needed by Microsoft DOS Virtual mem */
 65 #undef MAX_BSALLOC                                       /* bad with big blocks */
 66 #define MAX_BSALLOC 10000
 67 #endif
 68 
 69 /*****************************************************************************
 70 *
 71 *   Pointer Nlm_BSMerge(bsp, dest)
 72 *      if dest == NULL, allocates storage for merge and returns pointer to it
 73 *
 74 *****************************************************************************/
 75 NLM_EXTERN Nlm_VoidPtr LIBCALL  Nlm_BSMerge (Nlm_ByteStorePtr bsp, Nlm_VoidPtr dest)
 76 
 77 {
 78         Nlm_BytePtr tmp, from;
 79         Nlm_BSUnitPtr bsup;
 80     size_t size;
 81 
 82         if (bsp == NULL)
 83                 return NULL;
 84 
 85     size = Nlm_BSLen(bsp) + 1;
 86     if (size > SIZE_MAX) {
 87                 ErrPostEx(SEV_ERROR, 0, 0, "size[%u] is bigger then SIZE_MAX[%u]",
 88                         size, SIZE_MAX);
 89         /* should post an error here */
 90         return NULL;
 91     }
 92 
 93         if (dest == NULL)         /* allocate storage with room for null at end */
 94         {
 95                 dest = Nlm_MemNew(size);
 96                 if (dest == NULL) return dest;
 97         }
 98 
 99         tmp = (Nlm_BytePtr) dest;
100         bsup = bsp->chain;
101 
102         while (bsup != NULL)
103         {
104                 from = (Nlm_BytePtr) Nlm_HandLock(bsup->str);
105                 Nlm_MemCopy(tmp, from, bsup->len);
106                 Nlm_HandUnlock(bsup->str);
107                 tmp += bsup->len;
108                 bsup = bsup->next;
109         }
110 
111         return dest;
112 }
113 
114 /*****************************************************************************
115 *
116 *   ByteStorePtr Nlm_BSNew(len)
117 *       creates a big enough bytestore for len
118 *
119 *****************************************************************************/
120 NLM_EXTERN Nlm_ByteStorePtr LIBCALL Nlm_BSNew (Nlm_Int4 len)
121 
122 {
123         Nlm_ByteStorePtr bsp;
124         Nlm_Int4 added;
125 
126         bsp = (Nlm_ByteStorePtr) Nlm_MemNew(sizeof(ByteStore));
127         if (bsp == NULL)
128                 return NULL;
129 
130         added = Nlm_BSAdd(bsp, len, FALSE);
131         if (added < len)
132                 bsp = Nlm_BSFree(bsp);
133         return bsp;
134 }
135 
136 /*****************************************************************************
137 *
138 *   Int4 BSAdd(bsp, len, use_min_size)
139 *       adds len bytes BEFORE current bsp->seekptr
140 *       bsp->seekptr returned pointing at first added byte
141 *       returns bytes added
142 *       if (use_min_size) then does not add anything smaller than MIN_BSALLOC
143 *
144 *****************************************************************************/
145 NLM_EXTERN Nlm_Int4 LIBCALL Nlm_BSAdd (Nlm_ByteStorePtr bsp, Nlm_Int4 len, Nlm_Boolean use_min_size)
146 
147 {
148         Nlm_BSUnitPtr bsup,      /* current bsunit */
149                           ccbsup,    /* bsp->curchain */
150                                 lastbsup,    /* bsunit after added section  */
151                                 prevbsup;    /* bsunit before added section */
152         Nlm_BytePtr to, from;
153         Nlm_Int4 added = 0,
154                       tlen;
155         Nlm_Handle thand;
156 
157         if ((bsp == NULL) || (len == 0))
158                 return added;
159 
160         lastbsup = NULL;
161         prevbsup = NULL;
162         ccbsup = bsp->curchain;
163 
164         if (bsp->chain != NULL)        /* add or insert in exisiting chain */
165         {
166                 if (bsp->seekptr == bsp->chain_offset)   /* before start of block */
167                 {
168                         lastbsup = ccbsup;       /* it comes after */
169                         if (bsp->seekptr != 0)          /* something before it */
170                         {
171                                 prevbsup = bsp->chain;
172                                 while (prevbsup->next != ccbsup)
173                                         prevbsup = prevbsup->next;
174                         }
175                 }                                                                                /* at very end of data */
176                 else if (bsp->seekptr == (bsp->chain_offset + ccbsup->len))
177                 {
178                         prevbsup = ccbsup; /* JK */
179                 }                                                                                /* after all blocks */
180                 else if (bsp->seekptr >= (bsp->chain_offset + ccbsup->len_avail))
181                 {
182                         prevbsup = ccbsup;
183                 }
184                 else                /* split a bsunit */
185                 {
186                         bsup = (Nlm_BSUnitPtr) Nlm_MemNew(sizeof(Nlm_BSUnit));
187                         if (bsup == NULL) return added;
188                         if (bsp->chain_offset != 0)          /* not first BSUnit */
189                         {
190                                 prevbsup = bsp->chain;
191                                 while (prevbsup->next != ccbsup)
192                                         prevbsup = prevbsup->next;
193                                 prevbsup->next = bsup;      /* insert new bsunit */
194                         }
195                         else
196                             bsp->chain = bsup;
197                         bsup->next = ccbsup;
198                         tlen = bsp->seekptr - bsp->chain_offset;  /* len of first half */
199                         bsup->str = Nlm_HandNew((size_t) tlen);
200                         if (bsup->str == NULL) return added;
201                         bsup->len = (Nlm_Int2) tlen;
202                         bsup->len_avail = (Nlm_Int2) tlen;
203                         to = (Nlm_BytePtr) Nlm_HandLock(bsup->str);
204                         thand = ccbsup->str;
205                         from = (Nlm_BytePtr) Nlm_HandLock(thand);
206                         Nlm_MemCopy(to, from, (size_t) tlen);
207 #ifdef MSC_VIRT
208                         wrote_to_handle = TRUE;
209 #endif
210                         Nlm_HandUnlock(bsup->str);
211                         from += tlen;      /* point past copied region */
212                         tlen = ccbsup->len - tlen;    /* the last half */
213                         ccbsup->len = (Nlm_Int2) tlen;
214                         ccbsup->len_avail = (Nlm_Int2) tlen;
215                         ccbsup->str = Nlm_HandNew((size_t) tlen);
216                         if (ccbsup->str == NULL) return added;
217                         to = (Nlm_BytePtr) Nlm_HandLock(ccbsup->str);
218                         Nlm_MemCopy(to, from, (size_t) tlen);
219 #ifdef MSC_VIRT
220         wrote_to_handle = TRUE;
221 #endif
222                         Nlm_HandUnlock(ccbsup->str);
223                         Nlm_HandUnlock(thand);
224                         Nlm_HandFree(thand);
225                         prevbsup = bsup;
226                         lastbsup = ccbsup;
227                 }
228         }
229 
230         ccbsup = NULL;
231         bsup = NULL;
232         while (len)
233         {
234                 bsup = (Nlm_BSUnitPtr) Nlm_MemNew(sizeof(Nlm_BSUnit));
235                 if (bsup == NULL)
236                         return added;
237                 if (len < MAX_BSALLOC)
238 
239                 {
240                         if ((use_min_size) && (len < MIN_BSALLOC))
241                                 len = MIN_BSALLOC;
242                         tlen = len;
243                 }
244                 else
245                         tlen = MAX_BSALLOC;
246                 bsup->str = Nlm_HandNew((size_t)tlen);
247                 if (bsup->str == NULL)
248                 {
249                         Nlm_MemFree(bsup);
250                         return added;
251                 }
252                 bsup->len_avail = (Nlm_Int2) tlen;
253                 if (prevbsup == NULL)
254                         bsp->chain = bsup;
255                 else
256                         prevbsup->next = bsup;
257                 if (ccbsup == NULL)
258                         ccbsup = bsup;          /* current position */
259                 prevbsup = bsup;
260                 len -= tlen;
261                 added += tlen;
262         }
263         if (bsup != NULL)
264                 bsup->next = lastbsup;
265         bsp->curchain = ccbsup;
266         bsp->chain_offset = bsp->seekptr;   /* added block starts at seekptr */
267         return added;
268 }
269 
270 /*****************************************************************************
271 *
272 *   Int4 BSDelete(bsp, len)
273 *       deletes len bytes starting at current bsp->seekptr
274 *       returns bytes deleted
275 *
276 *****************************************************************************/
277 NLM_EXTERN Nlm_Int4 LIBCALL  Nlm_BSDelete (Nlm_ByteStorePtr bsp, Nlm_Int4 len)
278 
279 {
280         Nlm_BSUnitPtr bsup,      /* current bsunit */
281                           ccbsup,    /* bsp->curchain */
282                                 nextbsup,    /* bsunit after added section  */
283                                 prevbsup;    /* bsunit before added section */
284         Nlm_BytePtr to, from;
285         Nlm_Int4 added = 0,
286                       offset,
287                       tlen,
288                           start,
289                           save;
290         Nlm_Handle thand;
291 
292         if ((bsp == NULL) || (len == 0) || (bsp->chain == NULL) ||
293                 (bsp->seekptr >= bsp->totlen))
294                 return added;
295 
296         if ((bsp->seekptr + len) > bsp->totlen)   /* deleting too much */
297                 len = bsp->totlen - bsp->seekptr;
298 
299         nextbsup = NULL;
300         ccbsup = bsp->curchain;
301         start = bsp->chain_offset;
302         offset = bsp->seekptr - bsp->chain_offset;
303         if (offset)           /* will leave part of first bsunit */
304                 prevbsup = ccbsup;
305         else if (bsp->chain_offset != 0)          /* something before this bsunit */
306         {
307                 prevbsup = bsp->chain;
308                 while (prevbsup->next != ccbsup)
309                         prevbsup = prevbsup->next;
310         }
311         else
312                 prevbsup = NULL;       /* will remove beginning of first bsunit */
313 
314         bsup = ccbsup;
315         while (len)
316         {
317                 nextbsup = bsup->next;
318                 tlen = bsup->len - offset;
319                 if (tlen > len)
320                         tlen = len;                      /* will remove tlen bytes from this BSUnit*/
321                 save = bsup->len - tlen;
322                 if (save)    /* some bytes left after delete */
323                 {
324                         thand = bsup->str;
325                         bsup->str = Nlm_HandNew((size_t) save);
326                         if (bsup->str == NULL) return added;
327                         bsup->len = (Nlm_Int2) save;
328                         bsup->len_avail = (Nlm_Int2) save;
329                         to = (Nlm_BytePtr) Nlm_HandLock(bsup->str);
330                         from = (Nlm_BytePtr) Nlm_HandLock(thand);
331                         if (offset)         /* get the beginning */
332                                 Nlm_MemCopy(to, from, (size_t) offset);
333                         save -= offset;
334                         if (save)           /* save end */
335                                 Nlm_MemCopy((to + offset), (from + (offset + tlen)), (size_t)save);
336                         Nlm_HandUnlock(thand);
337                         Nlm_HandFree(thand);
338 #ifdef MSC_VIRT
339         wrote_to_handle = TRUE;
340 #endif
341                         Nlm_HandUnlock(bsup->str);
342                         if (tlen < len)
343                                 bsup = nextbsup;
344                 }
345                 else                    /* delete the whole thing */
346                 {
347                         Nlm_HandFree(bsup->str);
348                         Nlm_MemFree(bsup);
349                         bsup = nextbsup;
350                 }
351                 offset = 0;
352                 len -= tlen;
353                 added += tlen;
354         }
355         if ((bsup != prevbsup) ||   /* break in chain, rejoin it */
356              ((bsup == NULL) && (prevbsup == NULL)))   /* chain gone */
357         {
358                 if (prevbsup == NULL)
359                         bsp->chain = bsup;
360                 else
361                         prevbsup->next = bsup;
362         }
363         bsp->curchain = bsup;
364         bsp->totlen -= added;
365         if (bsp->totlen)
366         {
367                 offset = bsp->seekptr;
368                 start = 0;
369                 bsup = bsp->chain;
370                 while (offset >= (start + bsup->len_avail))
371                 {
372                         if (bsup->next == NULL)    /* EOF */
373                                 offset = 0;            /* stop loop */
374                         else
375                         {
376                                 start += bsup->len;
377                                 bsup = bsup->next;
378                         }
379                 }
380                 bsp->curchain = bsup;
381                 bsp->chain_offset = start;
382         }
383         else
384         {
385                 bsp->chain_offset = 0;
386                 bsp->curchain = bsp->chain;
387         }
388         return added;
389 }
390 
391 /*****************************************************************************
392 *
393 *   Nlm_Int4 Nlm_BSTell(bsp)
394 *
395 *****************************************************************************/
396 NLM_EXTERN Nlm_Int4 LIBCALL  Nlm_BSTell (Nlm_ByteStorePtr bsp)
397 
398 {
399         if (bsp == NULL)
400                 return 0L;
401 
402         return bsp->seekptr;
403 }
404 
405 /*****************************************************************************
406 *
407 *   Int2 Nlm_BSSeek(bsp, offset, origin)
408 *       seeks as fseek()
409 *       trys to lock a BSUnit at that seek position
410 *
411 *****************************************************************************/
412 NLM_EXTERN Nlm_Int2 LIBCALL  Nlm_BSSeek (Nlm_ByteStorePtr bsp, Nlm_Int4 offset, Nlm_Int2 origin)
413 
414 {
415         Nlm_Int4 sp, start = 0;
416         Nlm_BSUnitPtr bsup;
417         Nlm_Boolean done;
418 
419         if (bsp == NULL)
420                 return 1;
421         if (bsp->chain == NULL)
422                 return 1;
423 
424         sp = bsp->seekptr;
425 
426         switch (origin)
427         {
428                 case SEEK_SET:
429                         if ((offset > bsp->totlen) || (offset < 0))
430                                 return 1;
431                         sp = offset;
432                         break;
433                 case SEEK_CUR:
434                         if (((sp + offset) > bsp->totlen) ||
435                                 ((sp + offset) < 0 ))
436                                 return 1;
437                         sp += offset;
438                         break;
439                 case SEEK_END:
440                         if ((ABS(offset) > bsp->totlen) || (offset > 0))
441                                 return 1;
442                         sp = bsp->totlen + offset;
443                         break;
444                 default:
445                         return 1;
446         }
447 
448     if (sp == bsp->seekptr)     /* already in right position */
449         return 0;
450 
451         bsp->seekptr = sp;
452                                      /* if a valid seek, lock the right BSUnit */
453         bsup = bsp->curchain;
454 
455         if (sp == bsp->totlen)    /* seek to EOF */
456         {
457                 if (sp > (bsp->chain_offset + bsup->len_avail))
458                 {
459                         start = bsp->chain_offset;
460                         while (sp > (start + bsup->len_avail))
461                         {
462                                 start += bsup->len;
463                                 bsup = bsup->next;
464                         }
465                 }
466         }
467         else if ((sp < bsp->chain_offset) ||
468                 (sp >= (bsp->chain_offset + bsup->len)))
469         {
470                 if (sp < bsp->chain_offset)
471                 {
472                         bsup = bsp->chain;
473                         start = 0;
474                 }
475                 else
476                 {
477                         start = bsp->chain_offset + bsup->len;
478                         bsup = bsup->next;
479                 }
480                 done = FALSE;
481                 while (! done)
482                 {
483                         if ((start + bsup->len) > sp)
484                                 done = TRUE;
485                         else
486                         {
487                                 start += bsup->len;
488                                 bsup = bsup->next;
489                         }
490                 }
491         }
492         if (bsup != bsp->curchain)
493         {
494                 bsp->chain_offset = start;
495                 bsp->curchain = bsup;
496         }
497         return 0;
498 }
499 /*****************************************************************************
500 *
501 *   Int4 Nlm_BSLen(bsp)
502 *      gives cumulative length of strings in store (not counting \0)
503 *
504 *****************************************************************************/
505 NLM_EXTERN Nlm_Int4 LIBCALL  Nlm_BSLen (Nlm_ByteStorePtr bsp)
506 
507 {
508         if (bsp == NULL)
509                 return 0L;
510 
511         return bsp->totlen;
512 }
513 
514 /*****************************************************************************
515 *
516 *   Int2 BSPutByte(bsp, value)
517 *       - returns value on success, EOF on failure
518 *       - BSPutByte(bsp, EOF) truncates at seekptr
519 *
520 *****************************************************************************/
521 NLM_EXTERN Nlm_Int2 LIBCALL  Nlm_BSPutByte (Nlm_ByteStorePtr bsp, Nlm_Int2 value)
522 
523 {
524         Nlm_Uint1 b;
525     if (value == EOF)
526         Nlm_BSDelete(bsp, INT4_MAX);
527     else {
528         b = (Nlm_Uint1) value;
529         if (Nlm_BSWrite(bsp, (Nlm_VoidPtr)&b, 1) == 0)
530             return EOF;
531     }
532     return value;
533 }
534 
535 /*****************************************************************************
536 *
537 *   Int4 BSWrite(bsp, ptr, len)
538 *       returns bytes written from ptr to bsp
539 *       writes from current seekptr position
540 *       seekptr left pointing after last byte written
541 *       allocates storage if needed
542 *       writes over any data already there
543 *
544 *****************************************************************************/
545 NLM_EXTERN Nlm_Int4 LIBCALL  Nlm_BSWrite (Nlm_ByteStorePtr bsp, Nlm_VoidPtr ptr, Nlm_Int4 len)
546 
547 {
548         Nlm_BytePtr from, to;
549         Nlm_BSUnitPtr bsup;
550         Nlm_Int4 tlen, added = 0, offset, start, diff;
551 
552         if ((bsp == NULL) || (len <= 0))
553                 return added;
554 
555         bsup = bsp->curchain;
556         from = (Nlm_BytePtr) ptr;
557         offset = bsp->seekptr - bsp->chain_offset;
558         start = bsp->chain_offset;
559 
560 
561 
562         while (len)
563         {
564 
565                 if (bsup == NULL)
566                         tlen = 0;
567                 else
568                         tlen = bsup->len_avail - offset;
569                 if (len < tlen)
570                         tlen = len;
571                 if (! tlen)       /* out of space */
572                 {
573 
574                         if (Nlm_BSAdd(bsp, len, TRUE) < len)
575                                 return added;
576                         bsup = bsp->curchain;
577                         offset = bsp->seekptr - bsp->chain_offset;
578                         tlen = bsup->len_avail;
579 
580                         if (len < tlen)
581 
582                                 tlen = len;
583                 }
584                 else
585                 {
586                         bsp->chain_offset = start;
587                         bsp->curchain = bsup;
588                 }
589                 to = (Nlm_BytePtr)Nlm_HandLock(bsup->str) + offset;
590                 Nlm_MemCopy(to, from, (size_t) tlen);
591 #ifdef MSC_VIRT
592         wrote_to_handle = TRUE;
593 #endif
594                 Nlm_HandUnlock(bsup->str);
595                 if (bsup->len < (Nlm_Int2)(tlen + offset))   /* added more to this bsunit */
596                 {
597                         diff = (tlen + offset) - bsup->len;
598                         bsp->totlen += diff;
599                         bsup->len += (Nlm_Int2) diff;
600 
601                 }
602                 offset = 0;        /* only offset on first one */
603                 len -= tlen;
604                 bsp->seekptr += tlen;
605                 start += bsup->len;
606                 added += tlen;
607                 from += tlen;
608                 if (len)
609                         bsup = bsup->next;
610         }
611                          /* pointing past end of this BSunit */
612 
613         if ((bsp->seekptr - bsp->chain_offset) >= bsup->len_avail)
614         {
615                 if (bsup->next != NULL)      /* not end of space */
616                 {
617                         bsp->curchain = bsup->next;
618                         bsp->chain_offset += bsup->len;  /* should = len_avail */
619                 }
620         }
621         return added;
622 }
623 /*****************************************************************************
624 *
625 *   Int4 BSRead(bsp, ptr, len)
626 *       returns bytes read from bsp to ptr
627 *       reads from current seekptr position
628 *       seekptr left pointing after last byte read
629 *
630 *****************************************************************************/
631 NLM_EXTERN Nlm_Int4 LIBCALL  Nlm_BSRead (Nlm_ByteStorePtr bsp, Nlm_VoidPtr ptr, Nlm_Int4 len)
632 
633 {
634         Nlm_BytePtr from, to;
635         Nlm_BSUnitPtr bsup;
636         Nlm_Int4 tlen, added = 0, offset, start;
637 
638         if ((bsp == NULL) || (len <= 0))
639                 return added;
640 
641         bsup = bsp->curchain;
642         to = (Nlm_BytePtr) ptr;
643         offset = bsp->seekptr - bsp->chain_offset;
644         start = bsp->chain_offset;
645 
646         while (len)
647         {
648                 if (bsup == NULL)
649                         return added;
650                 tlen = bsup->len - offset;
651                 if (len < tlen)
652                         tlen = len;
653                 if (! tlen)       /* out of data */
654                         return added;
655                 bsp->chain_offset = start;
656                 from = (Nlm_BytePtr)Nlm_HandLock(bsup->str) + offset;
657                 Nlm_MemCopy(to, from, (size_t) tlen);
658                 Nlm_HandUnlock(bsup->str);
659                 offset = 0;        /* only offset on first one */
660                 len -= tlen;
661                 bsp->seekptr += tlen;
662                 bsp->curchain = bsup;
663                 start += bsup->len;
664                 added += tlen;
665                 to += tlen;
666                 if (len)
667                         bsup = bsup->next;
668         }                                    /*** end of this bsunit? **/
669         if ((bsp->seekptr - bsp->chain_offset) == bsup->len)
670         {
671                 if (bsup->next != NULL)    /* not EOF */
672                 {
673                         bsp->curchain = bsup->next;
674                         bsp->chain_offset += bsup->len;
675                 }
676         }
677         return added;
678 }
679 
680 /*****************************************************************************
681 *
682 *   Int2 BSGetByte(bsp)
683 *      reads a byte and increments the seekptr
684 *      returns EOF on End-Of-BS or error
685 *
686 *****************************************************************************/
687 NLM_EXTERN Nlm_Int2 LIBCALL  Nlm_BSGetByte (Nlm_ByteStorePtr bsp)
688 
689 {
690         Nlm_Int2 retval;
691         Nlm_BytePtr ptr;
692         Nlm_Int4 diff;
693         Nlm_BSUnitPtr bsup;
694 
695         if ((bsp == NULL) || (bsp->totlen == 0) || (bsp->seekptr == bsp->totlen))
696                 return EOF;      /* EOF */
697 
698         diff = bsp->seekptr - bsp->chain_offset;
699         bsup = bsp->curchain;
700         ptr = (Nlm_BytePtr) Nlm_HandLock(bsup->str);
701         retval = (Nlm_Int2) *(ptr + diff);
702         Nlm_HandUnlock(bsup->str);
703 
704         bsp->seekptr++;
705         diff++;
706         if (diff == bsup->len)
707         {
708                 if (bsp->seekptr != bsp->totlen)    /* not EOF */
709                 {
710                         bsp->curchain = bsup->next;
711                         bsp->chain_offset += bsup->len;
712                 }
713         }
714         return retval;  
715 }
716 
717 /*****************************************************************************
718 *
719 *   Int4 BSInsert(bsp, ptr, len)
720 *       returns bytes written from ptr into bsp
721 *       writes from current seekptr position
722 *       seekptr left pointing after last byte written
723 *       allocates storage if needed
724 *       inserts data BEFORE seekptr
725 *
726 *****************************************************************************/
727 NLM_EXTERN Nlm_Int4 LIBCALL  Nlm_BSInsert (Nlm_ByteStorePtr bsp, Nlm_VoidPtr ptr, Nlm_Int4 len)
728 
729 {
730         Nlm_Int4 added;
731 
732         added = Nlm_BSAdd(bsp, len, FALSE);
733         if (added != len)
734         {
735                 Nlm_BSDelete(bsp, added);
736                 return 0;
737         }
738         added = Nlm_BSWrite(bsp, ptr, len);
739         return added;
740 }
741 
742 /*****************************************************************************
743 *
744 *   Int4 BSInsertFromBS(bsp, bsp2, len)
745 *       returns bytes written from bsp2 into bsp
746 *       reads from bsp2 starting from current seek position
747 *       writes from current seekptr position
748 *       seekptr left pointing after last byte written
749 *       allocates storage if needed
750 *       inserts data BEFORE seekptr
751 *
752 *****************************************************************************/
753 NLM_EXTERN Nlm_Int4 LIBCALL  Nlm_BSInsertFromBS (Nlm_ByteStorePtr bsp, Nlm_ByteStorePtr bsp2, Nlm_Int4 len)
754 {
755         Nlm_Int4 added;
756         Nlm_Int2 x;
757 
758         added = Nlm_BSAdd(bsp, len, FALSE);
759         if (added != len)
760         {
761                 Nlm_BSDelete(bsp, added);
762                 return 0;
763         }
764 
765         for (added = 0; added < len; added++)
766         {
767                 x = Nlm_BSGetByte(bsp2);
768                 Nlm_BSPutByte(bsp, x);
769         }
770         return added;
771 }
772 
773 /*****************************************************************************
774 *
775 *   ByteStorePtr Nlm_BSFree(bsp)
776 *
777 *****************************************************************************/
778 NLM_EXTERN Nlm_ByteStorePtr LIBCALL  Nlm_BSFree (Nlm_ByteStorePtr bsp)
779 
780 {
781         Nlm_BSUnitPtr bsup, tmp;
782 
783         if (bsp == NULL)
784                 return NULL;
785                 
786         bsup = bsp->chain;
787         while (bsup != NULL)
788         {
789                 tmp = bsup;
790                 bsup = bsup->next;
791                 Nlm_HandFree(tmp->str);
792                 Nlm_MemFree(tmp);
793         }
794         return (Nlm_ByteStorePtr) Nlm_MemFree(bsp);
795 }
796 
797 /*****************************************************************************
798 *
799 *   ByteStorePtr Nlm_BSDup(bsp)
800 *
801 *****************************************************************************/
802 
803 #define BUFSIZE 256
804 
805 NLM_EXTERN Nlm_ByteStorePtr LIBCALL Nlm_BSDup (Nlm_ByteStorePtr source)
806 
807 {
808   Nlm_Byte          buf [BUFSIZE + 4];
809   Nlm_Int4          count;
810   Nlm_ByteStorePtr  dest;
811   Nlm_Int4          sourceLen;
812   Nlm_Int4          sourceLoc;
813 
814   dest = NULL;
815   if (source != NULL) {
816     sourceLen = Nlm_BSLen (source);
817     dest = Nlm_BSNew (sourceLen);
818     /* read the original location */
819     sourceLoc = Nlm_BSTell(source);
820     Nlm_BSSeek(source, 0L, SEEK_SET);
821     if (dest != NULL) {
822       count = MIN (sourceLen, (Nlm_Int4) BUFSIZE);
823       while (count > 0 && sourceLen > 0) {
824         Nlm_BSRead (source, buf, count);
825         Nlm_BSWrite (dest, buf, count);
826         sourceLen -= count;
827         count = MIN (sourceLen, (Nlm_Int4) BUFSIZE);
828       }
829       /* for neatness, make the duplicate point to the
830              same location as the old one */
831       Nlm_BSSeek(dest, sourceLoc, SEEK_SET);
832     }
833     /* restore original location */
834     Nlm_BSSeek(source, sourceLoc, SEEK_SET);
835   }
836   return dest;
837 }
838 
839 /*****************************************************************************
840 *
841 *   Boolean Nlm_BSEqual (bs1, bs2)
842 *
843 *****************************************************************************/
844 
845 NLM_EXTERN Nlm_Boolean LIBCALL Nlm_BSEqual (Nlm_ByteStorePtr bs1, Nlm_ByteStorePtr bs2)
846 
847 {
848   Nlm_Byte  buf1 [256], buf2 [256];
849   Nlm_Int4  count1, count2, idx;
850 
851   if (bs1 == NULL || bs2 == NULL) {
852     if (bs1 == NULL && bs2 == NULL) return TRUE;
853     if (Nlm_BSLen (bs1) == 0 && Nlm_BSLen (bs2) == 0) return TRUE;
854     return FALSE;
855   }
856 
857   Nlm_BSSeek (bs1, 0, SEEK_SET);
858   Nlm_BSSeek (bs2, 0, SEEK_SET);
859 
860   count1 = Nlm_BSRead (bs1, buf1, sizeof (buf1));
861   count2 = Nlm_BSRead (bs2, buf2, sizeof (buf2));
862 
863   while (count1 == count2 && count2 > 0) {
864     for (idx = 0; idx < count1; idx++) {
865       if (buf1 [idx] != buf2 [idx]) return FALSE;
866     }
867 
868     count1 = Nlm_BSRead (bs1, buf1, sizeof (buf1));
869     count2 = Nlm_BSRead (bs2, buf2, sizeof (buf2));
870   }
871 
872   if (count1 != count2) return FALSE;
873 
874   return TRUE;
875 }
876 
877 
878 /* for copying and swapping of UID lists passed over network to BIG_ENDIAN server */
879 
880 NLM_EXTERN Nlm_ByteStorePtr LIBCALL Nlm_BSDupAndSwapUint4 (Nlm_ByteStorePtr source)
881 
882 {
883   Nlm_Byte          buf [BUFSIZE + 4];
884   Nlm_Int4          count;
885   Nlm_ByteStorePtr  dest;
886   Nlm_Int4          sourceLen;
887   Nlm_Int4          sourceLoc;
888   Nlm_Int4          swapLen;
889 
890   dest = NULL;
891   if (source != NULL) {
892     sourceLen = Nlm_BSLen (source);
893     dest = Nlm_BSNew (sourceLen);
894     /* read the original location */
895     sourceLoc = Nlm_BSTell(source);
896     Nlm_BSSeek(source, 0L, SEEK_SET);
897     if (dest != NULL) {
898       count = MIN (sourceLen, (Nlm_Int4) BUFSIZE);
899       while (count > 0 && sourceLen > 0) {
900         swapLen = Nlm_BSRead (source, buf, count);
901         swapLen /= 4;
902         /* swap Uint4 if IS_LITTLE_ENDIAN */
903         Nlm_SwapUint4Buff ((Nlm_Uint4Ptr) buf, swapLen);
904         Nlm_BSWrite (dest, buf, count);
905         sourceLen -= count;
906         count = MIN (sourceLen, (Nlm_Int4) BUFSIZE);
907       }
908       /* for neatness, make the duplicate point to the
909              same location as the old one */
910       Nlm_BSSeek(dest, sourceLoc, SEEK_SET);
911     }
912     /* restore original location */
913     Nlm_BSSeek(source, sourceLoc, SEEK_SET);
914   }
915   return dest;
916 }
917 
918 /****************************************************************************
919 *
920 *   Integer storage utilities
921 *      These assume integers are store in BIG_ENDIAN order in the ByteStore
922 *      They read and write Uint2 or Uint4 in the NATIVE endian order
923 *      All work with UNSIGNED 2 or 4 byte integers
924 *         (you should cast to make them signed)
925 *      These are just helper functions. They do no internal consistency
926 *         checking.
927 *      They are primarily to facilitate encoding SEQUENCE OF INTEGER as
928 *         OCTET STRING for ASN.1
929 *
930 ****************************************************************************/
931 
932 NLM_EXTERN Nlm_Uint2 LIBCALL Nlm_BSGetUint2 (Nlm_ByteStorePtr bsp)
933 {
934         Nlm_Uint2 retval = 0;
935 
936         Nlm_BSRead(bsp, (Nlm_VoidPtr)(&retval), (Nlm_Int4)2);
937         Nlm_SwapUint2(retval);
938 
939         return retval;
940 }
941 
942 NLM_EXTERN Nlm_Uint4 LIBCALL Nlm_BSGetUint4 (Nlm_ByteStorePtr bsp)
943 {
944         Nlm_Uint4 retval = 0;
945 
946         Nlm_BSRead(bsp, (Nlm_VoidPtr)(&retval), (Nlm_Int4)4);
947         Nlm_SwapUint4(retval);
948 
949         return retval;
950 }
951 
952 NLM_EXTERN Nlm_Int2 LIBCALL Nlm_BSPutUint2 (Nlm_ByteStorePtr bsp, Nlm_Uint2 value)
953 {
954 #ifdef IS_LITTLE_ENDIAN
955         Nlm_SwitchUint2(value);
956 #endif
957         if (Nlm_BSWrite(bsp, (Nlm_VoidPtr)(&value), (Nlm_Int4)2) == (Nlm_Int2)2)
958                 return (Nlm_Int2)1;
959         else
960                 return (Nlm_Int2)0;
961 }
962 
963 NLM_EXTERN Nlm_Int2 LIBCALL Nlm_BSPutUint4 (Nlm_ByteStorePtr bsp, Nlm_Uint4 value)
964 {
965 #ifdef IS_LITTLE_ENDIAN
966         Nlm_SwitchUint4(value);
967 #endif
968         if (Nlm_BSWrite(bsp, (Nlm_VoidPtr)(&value), (Nlm_Int4)4) == (Nlm_Int2)4)
969                 return (Nlm_Int2)1;
970         else
971                 return (Nlm_Int2)0;
972 }
973 
974        /* In functions below, size is 2 or 4 */
975        /* Integers are converted from ByteStore to native endian (BSUintXRead) */
976            /*   or from native endian to ByteStore (BSUintXWrite) */
977            /* len is number of INTEGERS, not number of bytes */
978            /* returns count of integers put in ptr */
979            /* WARNING: On LITTLE_ENDIAN machines the data in ptr is changed to BIG_ENDIAN in the */
980            /*   XXWrite functions and LEFT THAT WAY */
981 NLM_EXTERN Nlm_Int4 LIBCALL Nlm_BSUint4Read (Nlm_ByteStorePtr bsp, Nlm_Uint4Ptr ptr, Nlm_Int4 len)
982 {
983         Nlm_Int4 len2;
984 
985         len2 = Nlm_BSRead(bsp, (Nlm_VoidPtr)ptr, (len * 4));
986         len2 /= 4;
987         Nlm_SwapUint4Buff(ptr, len2);
988         return len2;
989 }
990 
991 NLM_EXTERN Nlm_Int4 LIBCALL Nlm_BSUint4Write (Nlm_ByteStorePtr bsp, Nlm_Uint4Ptr ptr, Nlm_Int4 len)
992 {
993         Nlm_Int4 len2;
994 
995 #ifdef IS_LITTLE_ENDIAN
996         Nlm_SwitchUint4Buff(ptr, len);
997 #endif
998         len2 = Nlm_BSWrite(bsp, (Nlm_VoidPtr)ptr, (len * 4));
999         return (len2 / 4);
1000 }
1001 
1002 NLM_EXTERN Nlm_Int4 LIBCALL Nlm_BSUint2Read (Nlm_ByteStorePtr bsp, Nlm_Uint2Ptr ptr, Nlm_Int4 len)
1003 {
1004         Nlm_Int4 len2;
1005 
1006         len2 = Nlm_BSRead(bsp, (Nlm_VoidPtr)ptr, (len * 2));
1007         len2 /= 2;
1008         Nlm_SwapUint2Buff(ptr, len2);
1009         return len2;
1010 }
1011 
1012 NLM_EXTERN Nlm_Int4 LIBCALL Nlm_BSUint2Write (Nlm_ByteStorePtr bsp, Nlm_Uint2Ptr ptr, Nlm_Int4 len)
1013 {
1014         Nlm_Int4 len2;
1015 
1016 #ifdef IS_LITTLE_ENDIAN
1017         Nlm_SwitchUint2Buff(ptr, len);
1018 #endif
1019         len2 = Nlm_BSWrite(bsp, (Nlm_VoidPtr)ptr, (len * 2));
1020         return (len2 / 2);
1021 }
1022 
1023 

source navigation ]   [ diff markup ]   [ identifier search ]   [ freetext search ]   [ file search ]  

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.