MagickCore 7.0.10
blob.c
Go to the documentation of this file.
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% %
6% BBBB L OOO BBBB %
7% B B L O O B B %
8% BBBB L O O BBBB %
9% B B L O O B B %
10% BBBB LLLLL OOO BBBB %
11% %
12% %
13% Wizard's Toolkit Binary Large OBjectS Methods %
14% %
15% %
16% Software Design %
17% Cristy %
18% March 2003 %
19% %
20% %
21% Copyright @ 1999 ImageMagick Studio LLC, a non-profit organization %
22% dedicated to making software imaging solutions freely available. %
23% %
24% You may not use this file except in compliance with the License. You may %
25% obtain a copy of the License at %
26% %
27% https://imagemagick.org/script/license.php %
28% %
29% Unless required by applicable law or agreed to in writing, software %
30% distributed under the License is distributed on an "AS IS" BASIS, %
31% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %
32% See the License for the specific language governing permissions and %
33% limitations under the License. %
34% %
35%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
36%
37%
38%
39*/
40
41/*
42 Include declarations.
43*/
44#include "wizard/studio.h"
45#include "wizard/blob.h"
46#include "wizard/blob-private.h"
47#include "wizard/cipher.h"
48#include "wizard/exception.h"
50#include "wizard/memory_.h"
51#include "wizard/semaphore.h"
52#include "wizard/nt-base.h"
54#include "wizard/utility.h"
56#include "bzlib.h"
57#include "zlib.h"
58
59/*
60 Define declarations.
61*/
62#define WizardMaxBlobExtent (8*8192)
63# if !defined(MAP_ANONYMOUS) && defined(MAP_ANON)
64# define MAP_ANONYMOUS MAP_ANON
65# endif
66#if !defined(MAP_FAILED)
67#define MAP_FAILED ((void *) -1)
68#endif
69
70/*
71 Typedef declarations.
72*/
73typedef enum
74{
83
84typedef union BlobFileInfo
85{
86 FILE
88
89#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
90 gzFile
91 gzfile;
92#endif
93
94#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
95 BZFILE
96 *bzfile;
97#endif
99
101{
102 char
104
105 size_t
109
112
116
117 int
120
123
126
130
131 int
133
136
139
140 struct stat
142
143 unsigned char
145
148
151
152 ssize_t
154
155 size_t
157};
158
159/*
160 Forward declarations.
161*/
162static unsigned char
164
165/*
166%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
167% %
168% %
169% %
170+ A t t a c h B l o b %
171% %
172% %
173% %
174%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
175%
176% AttachBlob() attaches a blob to the BlobInfo structure.
177%
178% The format of the AttachBlob method is:
179%
180% void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
181%
182% A description of each parameter follows:
183%
184% o blob_info: the blob info.
185%
186% o blob: the character stream to attach.
187%
188% o length: the length in bytes of the blob.
189%
190*/
191static void AttachBlob(BlobInfo *blob_info,const void *blob,const size_t length)
192{
193 assert(blob_info != (BlobInfo *) NULL);
194 if (blob_info->debug != WizardFalse)
196 blob_info->length=length;
197 blob_info->extent=length;
198 blob_info->quantum=(size_t) WizardMaxBlobExtent;
199 blob_info->offset=0;
200 blob_info->type=BlobStream;
201 blob_info->file_info.file=(FILE *) NULL;
202 blob_info->data=(unsigned char *) blob;
203 blob_info->mapped=WizardFalse;
204}
205
206/*
207%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
208% %
209% %
210% %
211+ C l o s e B l o b %
212% %
213% %
214% %
215%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
216%
217% CloseBlob() closes a stream associated with the blob_info.
218%
219% The format of the CloseBlob method is:
220%
221% WizardBooleanType CloseBlob(BlobInfo *blob_info)
222%
223% A description of each parameter follows:
224%
225% o blob_info: the blob info.
226%
227*/
228
229static inline void ThrowBlobException(BlobInfo *blob_info)
230{
231 if ((blob_info->status == 0) && (errno != 0))
232 blob_info->error_number=errno;
233 blob_info->status=(-1);
234}
235
237{
238 int
239 status;
240
241 /*
242 Close blob_info file.
243 */
244 assert(blob_info != (BlobInfo *) NULL);
245 assert(blob_info->signature == WizardSignature);
246 if (blob_info->debug != WizardFalse)
248 blob_info->filename);
249 if (blob_info->type == UndefinedStream)
250 return(WizardTrue);
251 if (SyncBlob(blob_info) != 0)
252 ThrowBlobException(blob_info);
253 status=blob_info->status;
254 switch (blob_info->type)
255 {
256 case UndefinedStream:
257 break;
258 case StandardStream:
259 case FileStream:
260 case PipeStream:
261 {
262 if ((status != 0) && (ferror(blob_info->file_info.file) != 0))
263 ThrowBlobException(blob_info);
264 break;
265 }
266 case ZipStream:
267 {
268#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
269 status=Z_OK;
270 (void) gzerror(blob_info->file_info.gzfile,&status);
271 if (status != Z_OK)
272 ThrowBlobException(blob_info);
273#endif
274 break;
275 }
276 case BZipStream:
277 {
278#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
279 status=BZ_OK;
280 (void) BZ2_bzerror(blob_info->file_info.bzfile,&status);
281 if (status != BZ_OK)
282 ThrowBlobException(blob_info);
283#endif
284 break;
285 }
286 case BlobStream:
287 break;
288 }
289 blob_info->status=status;
290 blob_info->size=GetBlobSize(blob_info);
291 blob_info->eof=WizardFalse;
292 blob_info->error=0;
293 blob_info->mode=UndefinedBlobMode;
294 if (blob_info->exempt != WizardFalse)
295 {
296 blob_info->type=UndefinedStream;
297 return(blob_info->status != 0 ? WizardFalse : WizardTrue);
298 }
299 switch (blob_info->type)
300 {
301 case UndefinedStream:
302 case StandardStream:
303 break;
304 case FileStream:
305 {
306 if (blob_info->file_info.file != (FILE *) NULL)
307 {
308 status=fclose(blob_info->file_info.file);
309 if (status != 0)
310 ThrowBlobException(blob_info);
311 }
312 break;
313 }
314 case PipeStream:
315 {
316#if defined(WIZARDSTOOLKIT_HAVE_POPEN)
317 status=pclose(blob_info->file_info.file);
318 if (status != 0)
319 ThrowBlobException(blob_info);
320#endif
321 break;
322 }
323 case ZipStream:
324 {
325#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
326 status=gzclose(blob_info->file_info.gzfile);
327 if (status != Z_OK)
328 ThrowBlobException(blob_info);
329#endif
330 break;
331 }
332 case BZipStream:
333 {
334#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
335 BZ2_bzclose(blob_info->file_info.bzfile);
336#endif
337 break;
338 }
339 case BlobStream:
340 break;
341 }
342 (void) DetachBlob(blob_info);
343 blob_info->status=status;
344 return(blob_info->status != 0 ? WizardFalse : WizardTrue);
345}
346
347/*
348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349% %
350% %
351% %
352+ D e s t r o y B l o b %
353% %
354% %
355% %
356%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
357%
358% DestroyBlob() deallocates memory associated with a blob.
359%
360% The format of the DestroyBlob method is:
361%
362% BlobInfo *DestroyBlob(BlobInfo *blob_info)
363%
364% A description of each parameter follows:
365%
366% o blob_info: the blob info.
367%
368*/
370{
372 destroy;
373
374 assert(blob_info != (BlobInfo *) NULL);
375 assert(blob_info->signature == WizardSignature);
376 if (blob_info->debug != WizardFalse)
378 blob_info->filename);
379 destroy=WizardFalse;
380 LockSemaphoreInfo(blob_info->semaphore);
381 blob_info->reference_count--;
382 if (blob_info->reference_count == 0)
383 destroy=WizardTrue;
384 UnlockSemaphoreInfo(blob_info->semaphore);
385 if (destroy == WizardFalse)
386 return(blob_info);
387 (void) CloseBlob(blob_info);
388 if (blob_info->mapped != WizardFalse)
389 {
390 (void) UnmapBlob(blob_info->data,blob_info->length);
392 }
393 if (blob_info->semaphore != (SemaphoreInfo *) NULL)
395 blob_info->signature=(~WizardSignature);
396 blob_info=(BlobInfo *) RelinquishWizardMemory(blob_info);
397 return(blob_info);
398}
399
400/*
401%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
402% %
403% %
404% %
405+ D e t a c h B l o b %
406% %
407% %
408% %
409%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
410%
411% DetachBlob() detaches a blob from the BlobInfo structure.
412%
413% The format of the DetachBlob method is:
414%
415% unsigned char *DetachBlob(BlobInfo *blob_info)
416%
417% A description of each parameter follows:
418%
419% o blob_info: the blob info.
420%
421*/
422static unsigned char *DetachBlob(BlobInfo *blob_info)
423{
424 unsigned char
425 *data;
426
427 assert(blob_info != (BlobInfo *) NULL);
428 if (blob_info->debug != WizardFalse)
430 if (blob_info->mapped != WizardFalse)
431 {
432 (void) UnmapBlob(blob_info->data,blob_info->length);
433 blob_info->data=(unsigned char *) NULL;
435 }
436 blob_info->mapped=WizardFalse;
437 blob_info->length=0;
438 blob_info->offset=0;
439 blob_info->eof=WizardFalse;
440 blob_info->exempt=WizardFalse;
441 blob_info->type=UndefinedStream;
442 blob_info->file_info.file=(FILE *) NULL;
443 data=blob_info->data;
444 blob_info->data=(unsigned char *) NULL;
445 return(data);
446}
447
448/*
449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450% %
451% %
452% %
453+ E O F B l o b %
454% %
455% %
456% %
457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458%
459% EOFBlob() returns a non-zero value when EOF has been detected reading from
460% a blob or file.
461%
462% The format of the EOFBlob method is:
463%
464% int EOFBlob(BlobInfo *blob_info)
465%
466% A description of each parameter follows:
467%
468% o blob_info: the blob info.
469%
470*/
472{
473 assert(blob_info != (BlobInfo *) NULL);
474 assert(blob_info->signature == WizardSignature);
475 if (blob_info->debug != WizardFalse)
477 assert(blob_info->type != UndefinedStream);
478 switch (blob_info->type)
479 {
480 case UndefinedStream:
481 case StandardStream:
482 break;
483 case FileStream:
484 case PipeStream:
485 {
486 blob_info->eof=feof(blob_info->file_info.file) != 0 ? WizardTrue :
488 break;
489 }
490 case ZipStream:
491 {
492 blob_info->eof=WizardFalse;
493 break;
494 }
495 case BZipStream:
496 {
497#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
498 int
499 status;
500
501 status=0;
502 (void) BZ2_bzerror(blob_info->file_info.bzfile,&status);
503 blob_info->eof=status == BZ_UNEXPECTED_EOF ? WizardTrue : WizardFalse;
504#endif
505 break;
506 }
507 case BlobStream:
508 break;
509 }
510 return((int) blob_info->eof);
511}
512
513/*
514%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
515% %
516% %
517% %
518% F i l e T o B l o b %
519% %
520% %
521% %
522%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
523%
524% FileToBlob() returns the contents of a file as a blob. It returns the
525% file as a blob and its length. If an error occurs, NULL is returned.
526%
527% The format of the FileToBlob method is:
528%
529% void *FileToBlob(const char *filename,const size_t extent,size_t *length,
530% ExceptionInfo *exception)
531%
532% A description of each parameter follows:
533%
534% o blob: FileToBlob() returns the contents of a file as a blob. If
535% an error occurs NULL is returned.
536%
537% o filename: The filename.
538%
539% o extent: The maximum length of the blob.
540%
541% o length: On return, it reflects the actual length of the blob.
542%
543% o exception: Return any errors or warnings in this structure.
544%
545*/
546WizardExport void *FileToBlob(const char *filename,const size_t extent,
547 size_t *length,ExceptionInfo *exception)
548{
549 int
550 file;
551
552 size_t
553 i;
554
555 ssize_t
556 count;
557
558 unsigned char
559 *blob;
560
562 offset;
563
564 void
565 *map;
566
567 assert(filename != (const char *) NULL);
568 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",filename);
569 assert(exception != (ExceptionInfo *) NULL);
570 *length=0;
571 file=fileno(stdin);
572 if (strcmp(filename,"-") != 0)
573 file=open_utf8(filename,O_RDONLY | O_BINARY,0);
574 if (file == -1)
575 {
577 "unable to open file `%s': %s",filename,strerror(errno));
578 return(NULL);
579 }
580 offset=(WizardOffsetType) lseek(file,0,SEEK_END);
581 count=0;
582 if ((file == fileno(stdin)) || (offset < 0) ||
583 (offset != (WizardOffsetType) ((ssize_t) offset)))
584 {
585 size_t
586 quantum;
587
588 struct stat
589 file_info;
590
591 /*
592 Stream is not seekable.
593 */
594 offset=(WizardOffsetType) lseek(file,0,SEEK_SET);
595 quantum=(size_t) WizardMaxBufferExtent;
596 if ((fstat(file,&file_info) == 0) && (file_info.st_size > 0))
597 quantum=Min((size_t) file_info.st_size,WizardMaxBufferExtent);
598 blob=(unsigned char *) AcquireQuantumMemory(quantum,sizeof(*blob));
599 for (i=0; blob != (unsigned char *) NULL; i+=count)
600 {
601 count=read(file,blob+i,quantum);
602 if (count <= 0)
603 {
604 count=0;
605 if (errno != EINTR)
606 break;
607 }
608 if (~((size_t) i) < (quantum+1))
609 {
610 blob=(unsigned char *) RelinquishWizardMemory(blob);
611 break;
612 }
613 blob=(unsigned char *) ResizeQuantumMemory(blob,i+quantum+1,
614 sizeof(*blob));
615 if ((size_t) (i+count) >= extent)
616 break;
617 }
618 if (close(file) == -1)
620 "unable to close file `%s': %s",filename,strerror(errno));
621 if (blob == (unsigned char *) NULL)
622 {
624 "memory allocation failed: `%s'",filename);
625 return(NULL);
626 }
627 *length=Min(i+count,extent);
628 blob[*length]='\0';
629 return(blob);
630 }
631 *length=Min((size_t) offset,extent);
632 blob=(unsigned char *) NULL;
633 if (~(*length) >= (MaxCipherBlocksize-1))
634 blob=(unsigned char *) AcquireQuantumMemory(*length+MaxCipherBlocksize,
635 sizeof(*blob));
636 if (blob == (unsigned char *) NULL)
637 {
638 if (close(file) == -1)
639 {
641 "unable to close file `%s': %s",filename,strerror(errno));
642 return((unsigned char *) NULL);
643 }
645 "memory allocation failed `%s'",strerror(errno));
646 return(NULL);
647 }
648 map=MapBlob(file,ReadMode,0,*length);
649 if (map != (void *) NULL)
650 {
651 (void) memcpy(blob,map,*length);
652 if (UnmapBlob(map,*length) == WizardFalse)
654 "unable to unmap blob `%s': %s",filename,strerror(errno));
655 }
656 else
657 {
658 size_t
659 i;
660
661 ssize_t
662 count;
663
664 if (lseek(file,0,SEEK_SET) < 0)
666 "unable to seek blob `%s': %s",filename,strerror(errno));
667 for (i=0; i < *length; i+=count)
668 {
669 count=read(file,blob+i,Min(*length-i,(size_t) SSIZE_MAX));
670 if (count <= 0)
671 {
672 count=0;
673 if (errno != EINTR)
674 break;
675 }
676 }
677 if (i < *length)
678 {
679 if (close(file) == -1)
681 "unable to close file `%s': %s",filename,strerror(errno));
682 blob=(unsigned char *) RelinquishWizardMemory(blob);
684 "unable to read file `%s'",filename);
685 return(NULL);
686 }
687 }
688 if (close(file) == -1)
690 "unable to close file `%s': %s",filename,strerror(errno));
691 blob[*length]=(unsigned char) '\0';
692 return(blob);
693}
694
695/*
696%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
697% %
698% %
699% %
700+ G e t B l o b F i l e n a m e %
701% %
702% %
703% %
704%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
705%
706% GetBlobFilename() returns the blob filename.
707%
708% The format of the GetBlobFilename method is:
709%
710% const char *GetBlobFilename(const BlobInfo *blob_info)
711%
712% A description of each parameter follows:
713%
714% o blob_info: the blob info info.
715%
716*/
717WizardExport const char *GetBlobFilename(const BlobInfo *blob_info)
718{
719 assert(blob_info != (BlobInfo *) NULL);
720 if (blob_info->debug != WizardFalse)
722 blob_info->filename);
723 return(blob_info->filename);
724}
725
726/*
727%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
728% %
729% %
730% %
731+ G e t B l o b I n f o %
732% %
733% %
734% %
735%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
736%
737% GetBlobInfo() initializes the BlobInfo structure.
738%
739% The format of the GetBlobInfo method is:
740%
741% void GetBlobInfo(BlobInfo *blob_info)
742%
743% A description of each parameter follows:
744%
745% o blob_info: Specifies a pointer to a BlobInfo structure.
746%
747*/
749{
750 assert(blob_info != (BlobInfo *) NULL);
751 (void) memset(blob_info,0,sizeof(*blob_info));
752 blob_info->type=UndefinedStream;
753 blob_info->quantum=(size_t) WizardMaxBlobExtent;
754 blob_info->debug=IsEventLogging();
755 blob_info->reference_count=1;
756 blob_info->semaphore=AcquireSemaphoreInfo();
757 blob_info->signature=WizardSignature;
758}
759
760/*
761%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
762% %
763% %
764% %
765+ G e t B l o b S i z e %
766% %
767% %
768% %
769%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
770%
771% GetBlobSize() returns the current length of the blob; zero is returned if
772% the size cannot be determined.
773%
774% The format of the GetBlobSize method is:
775%
776% WizardSizeType GetBlobSize(BlobInfo *blob_info)
777%
778% A description of each parameter follows:
779%
780% o blob_info: the blob info.
781%
782*/
783
784static WizardBooleanType GetPathAttributes(const char *path,void *attributes)
785{
787 status;
788
789 if (path == (const char *) NULL)
790 {
791 errno=EINVAL;
792 return(WizardFalse);
793 }
794 (void) memset(attributes,0,sizeof(struct stat));
795 status=stat_utf8(path,(struct stat *) attributes) == 0 ? WizardTrue :
797 return(status);
798}
799
801{
803 extent;
804
805 assert(blob_info != (BlobInfo *) NULL);
806 if (blob_info->debug != WizardFalse)
808 blob_info->filename);
809 extent=0;
810 switch (blob_info->type)
811 {
812 case UndefinedStream:
813 case StandardStream:
814 {
815 extent=blob_info->size;
816 break;
817 }
818 case FileStream:
819 {
820 int
821 file_descriptor;
822
823 extent=(WizardSizeType) blob_info->properties.st_size;
824 if (extent == 0)
825 extent=blob_info->size;
826 file_descriptor=fileno(blob_info->file_info.file);
827 if (file_descriptor == -1)
828 break;
829 if (fstat(file_descriptor,&blob_info->properties) == 0)
830 extent=(WizardSizeType) blob_info->properties.st_size;
831 break;
832 }
833 case PipeStream:
834 {
835 extent=blob_info->size;
836 break;
837 }
838 case ZipStream:
839 case BZipStream:
840 {
841#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
843 status;
844
845 status=GetPathAttributes(blob_info->filename,&blob_info->properties);
846 if (status != WizardFalse)
847 extent=(WizardSizeType) blob_info->properties.st_size;
848#endif
849 break;
850 }
851 case BlobStream:
852 {
853 extent=(WizardSizeType) blob_info->extent;
854 break;
855 }
856 }
857 return(extent);
858}
859
860/*
861%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
862% %
863% %
864% %
865% G e t B l o b P r o p e r t i e s %
866% %
867% %
868% %
869%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
870%
871% GetBlobProperties() returns information about a blob.
872%
873% The format of the GetBlobProperties method is:
874%
875% const struct stat *GetBlobProperties(const BlobInfo *blob_info)
876%
877% A description of each parameter follows:
878%
879% o blob_info: the blob info.
880%
881*/
882WizardExport const struct stat *GetBlobProperties(const BlobInfo *blob_info)
883{
884 assert(blob_info != (BlobInfo *) NULL);
885 if (blob_info->debug != WizardFalse)
887 blob_info->filename);
888 return(&blob_info->properties);
889}
890
891/*
892%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
893% %
894% %
895% %
896+ M a p B l o b %
897% %
898% %
899% %
900%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
901%
902% MapBlob() creates a mapping from a file to a binary large object.
903%
904% The format of the MapBlob method is:
905%
906% void *MapBlob(int file,const MapMode mode,const WizardOffsetType offset,
907% const size_t length)
908%
909% A description of each parameter follows:
910%
911% o file: map this file descriptor.
912%
913% o mode: ReadMode, WriteMode, or IOMode.
914%
915% o offset: starting at this offset within the file.
916%
917% o length: the length of the mapping is returned in this pointer.
918%
919*/
920WizardExport void *MapBlob(int file,const MapMode mode,
921 const WizardOffsetType offset,const size_t length)
922{
923#if defined(WIZARDSTOOLKIT_HAVE_MMAP_FILEIO)
924 int
925 flags,
926 protection;
927
928 unsigned char
929 *map;
930
931 /*
932 Map file.
933 */
934 flags=0;
935 if (file == -1)
936#if defined(MAP_ANONYMOUS)
937 flags|=MAP_ANONYMOUS;
938#else
939 return((unsigned char *) NULL);
940#endif
941 flags|=MAP_PRIVATE;
942 switch (mode)
943 {
944 case ReadMode:
945 default:
946 {
947 protection=PROT_READ;
948 flags|=MAP_PRIVATE;
949 break;
950 }
951 case WriteMode:
952 {
953 protection=PROT_WRITE;
954 flags|=MAP_SHARED;
955 break;
956 }
957 case IOMode:
958 {
959 protection=PROT_READ | PROT_WRITE;
960 flags|=MAP_SHARED;
961 break;
962 }
963 }
964#if !defined(WIZARDSTOOLKIT_HAVE_HUGEPAGES) || !defined(MAP_HUGETLB)
965 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
966 (off_t) offset);
967#else
968 map=(unsigned char *) mmap((char *) NULL,length,protection,flags |
969 MAP_HUGETLB,file,(off_t) offset);
970 if (map == (unsigned char *) MAP_FAILED)
971 map=(unsigned char *) mmap((char *) NULL,length,protection,flags,file,
972 (off_t) offset);
973#endif
974 if (map == (unsigned char *) MAP_FAILED)
975 return((unsigned char *) NULL);
976 return(map);
977#else
978 return((unsigned char *) NULL);
979#endif
980}
981
982/*
983%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
984% %
985% %
986% %
987+ O p e n B l o b %
988% %
989% %
990% %
991%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
992%
993% OpenBlob() opens a file associated with the blob. A file name of '-' sets
994% the file to stdin for type 'r' and stdout for type 'w'. If the filename
995% suffix is '.gz' or '.Z', the blob_info is decompressed for type 'r' and
996% compressed for type 'w'. If the filename prefix is '|', it is piped to or
997% from a system command.
998%
999% The format of the OpenBlob method is:
1000%
1001% BlobInfo *OpenBlob(const char *filename,const BlobMode mode,
1002% const WizardBooleanType compress,ExceptionInfo *exception)
1003%
1004% A description of each parameter follows:
1005%
1006% o filename: the filename.
1007%
1008% o mode: the mode for opening the file.
1009%
1010% o compress: a value other than 0 (de)compresses BZIP or ZIP files.
1011%
1012% o exception: return any errors or warnings in this structure.
1013*/
1014WizardExport BlobInfo *OpenBlob(const char *filename,const BlobMode mode,
1015 const WizardBooleanType compress,ExceptionInfo *exception)
1016{
1017 BlobInfo
1018 *blob_info;
1019
1020 const char
1021 *type;
1022
1024 status;
1025
1026 assert(filename != (const char *) NULL);
1027 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",filename);
1028 assert(exception != (ExceptionInfo *) NULL);
1029 blob_info=(BlobInfo *) AcquireWizardMemory(sizeof(*blob_info));
1030 if (blob_info == (BlobInfo *) NULL)
1031 {
1033 "memory allocation failed: `%s'",filename);
1034 return((BlobInfo *) NULL);
1035 }
1036 GetBlobInfo(blob_info);
1037 switch (mode)
1038 {
1039 default: type="r"; break;
1040 case ReadBlobMode: type="r"; break;
1041 case ReadBinaryBlobMode: type="rb"; break;
1042 case WriteBlobMode: type="w"; break;
1043 case WriteBinaryBlobMode: type="w+b"; break;
1044 }
1045 /*
1046 Open file.
1047 */
1048 (void) CopyWizardString(blob_info->filename,filename,WizardPathExtent);
1049 if (LocaleCompare(filename,"-") == 0)
1050 {
1051 blob_info->file_info.file=(*type == 'r') ? stdin : stdout;
1052#if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
1053 if (strchr(type,'b') != (char *) NULL)
1054 setmode(_fileno(blob_info->file_info.file),_O_BINARY);
1055#endif
1056 blob_info->type=FileStream;
1057 blob_info->exempt=WizardTrue;
1058 return(blob_info);
1059 }
1060 if (LocaleNCompare(filename,"fd:",3) == 0)
1061 {
1062 char
1063 mode[WizardPathExtent];
1064
1065 *mode=(*type);
1066 mode[1]='\0';
1067 blob_info->file_info.file=fdopen((long) StringToLong(filename+3),mode);
1068 if (blob_info->file_info.file == (FILE *) NULL)
1069 {
1071 "unable to open file `%s': %s",filename,strerror(errno));
1072 blob_info=(BlobInfo *) RelinquishWizardMemory(blob_info);
1073 return((BlobInfo *) NULL);
1074 }
1075#if defined(WIZARDSTOOLKIT_WINDOWS_SUPPORT)
1076 if (strchr(type,'b') != (char *) NULL)
1077 setmode(_fileno(blob_info->file_info.file),_O_BINARY);
1078#endif
1079 blob_info->type=FileStream;
1080 blob_info->exempt=WizardTrue;
1081 return(blob_info);
1082 }
1083#if defined(WIZARDSTOOLKIT_HAVE_POPEN)
1084 if (*filename == '|')
1085 {
1086 char
1087 mode[WizardPathExtent];
1088
1089 /*
1090 Pipe blob_info to or from a system command.
1091 */
1092#if defined(SIGPIPE)
1093 if (*type == 'w')
1094 (void) signal(SIGPIPE,SIG_IGN);
1095#endif
1096 *mode=(*type);
1097 mode[1]='\0';
1098 blob_info->file_info.file=(FILE *) popen_utf8(filename+1,mode);
1099 if (blob_info->file_info.file == (FILE *) NULL)
1100 {
1102 "unable to open file `%s': %s",filename,strerror(errno));
1103 blob_info=(BlobInfo *) RelinquishWizardMemory(blob_info);
1104 return((BlobInfo *) NULL);
1105 }
1106 blob_info->type=PipeStream;
1107 blob_info->exempt=WizardTrue;
1108 return(blob_info);
1109 }
1110#endif
1111 status=stat_utf8(filename,&blob_info->properties) == 0 ? WizardTrue :
1113#if defined(S_ISFIFO)
1114 if ((status == WizardTrue) && S_ISFIFO(blob_info->properties.st_mode))
1115 {
1116 blob_info->file_info.file=fopen_utf8(filename,type);
1117 if (blob_info->file_info.file == (FILE *) NULL)
1118 {
1120 "unable to open file `%s': %s",filename,strerror(errno));
1121 blob_info=(BlobInfo *) RelinquishWizardMemory(blob_info);
1122 return((BlobInfo *) NULL);
1123 }
1124 blob_info->type=FileStream;
1125 blob_info->exempt=WizardTrue;
1126 return(blob_info);
1127 }
1128#endif
1129 if (*type == 'r')
1130 {
1131 blob_info->file_info.file=fopen_utf8(filename,type);
1132 if (blob_info->file_info.file != (FILE *) NULL)
1133 {
1134 size_t
1135 length;
1136
1137 ssize_t
1138 count;
1139
1140 unsigned char
1141 magick[3];
1142
1143 blob_info->type=FileStream;
1144#if defined(WIZARDSTOOLKIT_HAVE_SETVBUF)
1145 (void) setvbuf(blob_info->file_info.file,(char *) NULL,(int) _IOFBF,
1146 16384);
1147#endif
1148 (void) memset(magick,0,sizeof(magick));
1149 count=(ssize_t) fread(magick,1,sizeof(magick),
1150 blob_info->file_info.file);
1151 (void) fseek(blob_info->file_info.file,-((off_t) count),SEEK_CUR);
1152#if defined(WIZARDSTOOLKIT_POSIX_SUPPORT)
1153 (void) fflush(blob_info->file_info.file);
1154#endif
1156 " read %.20g magic header bytes",(double) count);
1157#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
1158 if ((compress != WizardFalse) && ((int) magick[0] == 0x1F) &&
1159 ((int) magick[1] == 0x8B) && ((int) magick[2] == 0x08))
1160 {
1161 if (blob_info->file_info.file != (FILE *) NULL)
1162 (void) fclose(blob_info->file_info.file);
1163 blob_info->file_info.file=(FILE *) NULL;
1164 blob_info->file_info.gzfile=gzopen(filename,"rb");
1165 if (blob_info->file_info.gzfile != (gzFile) NULL)
1166 blob_info->type=ZipStream;
1167 }
1168#endif
1169#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
1170 if ((compress != WizardFalse) &&
1171 (strncmp((char *) magick,"BZh",3) == 0))
1172 {
1173 if (blob_info->file_info.file != (FILE *) NULL)
1174 (void) fclose(blob_info->file_info.file);
1175 blob_info->file_info.file=(FILE *) NULL;
1176 blob_info->file_info.bzfile=BZ2_bzopen(filename,"r");
1177 if (blob_info->file_info.bzfile != (BZFILE *) NULL)
1178 blob_info->type=BZipStream;
1179 }
1180#endif
1181 length=(size_t) blob_info->properties.st_size;
1182 if ((blob_info->type == FileStream) &&
1183 (blob_info->file_info.file != (FILE *) NULL) &&
1184 (length > WizardMaxBufferExtent) &&
1186 {
1187 void
1188 *blob;
1189
1190 blob=MapBlob(fileno(blob_info->file_info.file),ReadMode,0,length);
1191 if (blob == (void *) NULL)
1193 else
1194 {
1195 /*
1196 Use memory-mapped I/O.
1197 */
1198 (void) fclose(blob_info->file_info.file);
1199 blob_info->file_info.file=(FILE *) NULL;
1200 AttachBlob(blob_info,blob,length);
1201 blob_info->mapped=WizardTrue;
1202 }
1203 }
1204 }
1205 }
1206 else
1207 {
1208 char
1209 extension[WizardPathExtent];
1210
1211 GetPathComponent(filename,ExtensionPath,extension);
1212#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
1213 if ((compress != WizardFalse) &&
1214 ((LocaleCompare(extension,"Z") == 0) ||
1215 (LocaleCompare(extension,"gz") == 0)))
1216 {
1217 blob_info->file_info.gzfile=gzopen(filename,"wb");
1218 if (blob_info->file_info.gzfile != (gzFile) NULL)
1219 blob_info->type=ZipStream;
1220 }
1221 else
1222#endif
1223#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
1224 if ((compress != WizardFalse) && (LocaleCompare(extension,"bz2") == 0))
1225 {
1226 blob_info->file_info.bzfile=BZ2_bzopen(filename,"w");
1227 if (blob_info->file_info.bzfile != (BZFILE *) NULL)
1228 blob_info->type=BZipStream;
1229 }
1230 else
1231#endif
1232 {
1233 blob_info->file_info.file=fopen_utf8(filename,type);
1234 if (blob_info->file_info.file != (FILE *) NULL)
1235 {
1236 blob_info->type=FileStream;
1237#if defined(WIZARDSTOOLKIT_HAVE_SETVBUF)
1238 (void) setvbuf(blob_info->file_info.file,(char *) NULL,(int) _IOFBF,
1239 16384);
1240#endif
1241 }
1242 }
1243 }
1244 blob_info->status=WizardFalse;
1245 if (blob_info->type != UndefinedStream)
1246 blob_info->size=GetBlobSize(blob_info);
1247 else
1248 {
1250 "unable to open file `%s': %s",filename,strerror(errno));
1251 blob_info=(BlobInfo *) RelinquishWizardMemory(blob_info);
1252 return((BlobInfo *) NULL);
1253 }
1254 return(blob_info);
1255}
1256
1257/*
1258%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1259% %
1260% %
1261% %
1262+ R e a d B l o b %
1263% %
1264% %
1265% %
1266%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1267%
1268% ReadBlob() reads data from the blob or file and returns it. It
1269% returns the number of bytes read. If length is zero, ReadBlob() returns
1270% zero and has no other results. If length is greater than SSIZE_MAX, the
1271% result is unspecified.
1272%
1273% The format of the ReadBlob method is:
1274%
1275% ssize_t ReadBlob(BlobInfo *blob_info,const size_t length,void *data)
1276%
1277% A description of each parameter follows:
1278%
1279% o blob_info: the blob info.
1280%
1281% o length: number of bytes to read from the blob.
1282%
1283% o data: area to place the information requested from the blob.
1284%
1285*/
1286WizardExport ssize_t ReadBlob(BlobInfo *blob_info,const size_t length,
1287 void *data)
1288{
1289 int
1290 c;
1291
1292 unsigned char
1293 *q;
1294
1295 ssize_t
1296 count;
1297
1298 assert(blob_info != (BlobInfo *) NULL);
1299 assert(blob_info->signature == WizardSignature);
1300 assert(blob_info != (BlobInfo *) NULL);
1301 assert(blob_info->type != UndefinedStream);
1302 if (length == 0)
1303 return(0);
1304 assert(data != (void *) NULL);
1305 count=0;
1306 q=(unsigned char *) data;
1307 switch (blob_info->type)
1308 {
1309 case UndefinedStream:
1310 break;
1311 case StandardStream:
1312 case FileStream:
1313 case PipeStream:
1314 {
1315 switch (length)
1316 {
1317 default:
1318 {
1319 count=(ssize_t) fread(q,1,length,blob_info->file_info.file);
1320 break;
1321 }
1322 case 4:
1323 {
1324 c=getc(blob_info->file_info.file);
1325 if (c == EOF)
1326 break;
1327 *q++=(unsigned char) c;
1328 count++;
1329 }
1330 case 3:
1331 {
1332 c=getc(blob_info->file_info.file);
1333 if (c == EOF)
1334 break;
1335 *q++=(unsigned char) c;
1336 count++;
1337 }
1338 case 2:
1339 {
1340 c=getc(blob_info->file_info.file);
1341 if (c == EOF)
1342 break;
1343 *q++=(unsigned char) c;
1344 count++;
1345 }
1346 case 1:
1347 {
1348 c=getc(blob_info->file_info.file);
1349 if (c == EOF)
1350 break;
1351 *q++=(unsigned char) c;
1352 count++;
1353 }
1354 case 0:
1355 break;
1356 }
1357 break;
1358 }
1359 case ZipStream:
1360 {
1361#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
1362 switch (length)
1363 {
1364 default:
1365 {
1366 count=(ssize_t) gzread(blob_info->file_info.gzfile,q,(unsigned int)
1367 length);
1368 break;
1369 }
1370 case 4:
1371 {
1372 c=gzgetc(blob_info->file_info.gzfile);
1373 if (c == EOF)
1374 break;
1375 *q++=(unsigned char) c;
1376 count++;
1377 }
1378 case 3:
1379 {
1380 c=gzgetc(blob_info->file_info.gzfile);
1381 if (c == EOF)
1382 break;
1383 *q++=(unsigned char) c;
1384 count++;
1385 }
1386 case 2:
1387 {
1388 c=gzgetc(blob_info->file_info.gzfile);
1389 if (c == EOF)
1390 break;
1391 *q++=(unsigned char) c;
1392 count++;
1393 }
1394 case 1:
1395 {
1396 c=gzgetc(blob_info->file_info.gzfile);
1397 if (c == EOF)
1398 break;
1399 *q++=(unsigned char) c;
1400 count++;
1401 }
1402 case 0:
1403 break;
1404 }
1405#endif
1406 break;
1407 }
1408 case BZipStream:
1409 {
1410#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
1411 count=(ssize_t) BZ2_bzread(blob_info->file_info.bzfile,q,(int) length);
1412#endif
1413 break;
1414 }
1415 case BlobStream:
1416 {
1417 const unsigned char
1418 *p;
1419
1420 if (blob_info->offset >= (WizardOffsetType) blob_info->length)
1421 {
1422 blob_info->eof=WizardTrue;
1423 break;
1424 }
1425 p=blob_info->data+blob_info->offset;
1426 count=(ssize_t) WizardMin(length,blob_info->length-blob_info->offset);
1427 blob_info->offset+=count;
1428 if (count != (ssize_t) length)
1429 blob_info->eof=WizardTrue;
1430 (void) memcpy(q,p,(size_t) count);
1431 break;
1432 }
1433 }
1434 return(count);
1435}
1436
1437/*
1438%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1439% %
1440% %
1441% %
1442+ R e a d B l o b B y t e %
1443% %
1444% %
1445% %
1446%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1447%
1448% ReadBlobByte() reads a single byte from the blob_info file and returns it.
1449%
1450% The format of the ReadBlobByte method is:
1451%
1452% int ReadBlobByte(BlobInfo *blob_info)
1453%
1454% A description of each parameter follows.
1455%
1456% o blob_info: the blob info.
1457%
1458*/
1459
1460static inline const void *ReadBlobStream(BlobInfo *blob_info,
1461 const size_t length,void *data,ssize_t *count)
1462{
1463 assert(count != (ssize_t *) NULL);
1464 assert(blob_info != (BlobInfo *) NULL);
1465 if (blob_info->type != BlobStream)
1466 {
1467 *count=ReadBlob(blob_info,length,data);
1468 return(data);
1469 }
1470 if (blob_info->offset >= (WizardOffsetType) blob_info->length)
1471 {
1472 *count=0;
1473 blob_info->eof=WizardTrue;
1474 return(data);
1475 }
1476 data=blob_info->data+blob_info->offset;
1477 *count=(ssize_t) WizardMin(length,blob_info->length-blob_info->offset);
1478 blob_info->offset+=(*count);
1479 if (*count != (ssize_t) length)
1480 blob_info->eof=WizardTrue;
1481 return(data);
1482}
1483
1485{
1486 const unsigned char
1487 *p;
1488
1489 ssize_t
1490 count;
1491
1492 unsigned char
1493 buffer[1];
1494
1495 assert(blob_info != (BlobInfo *) NULL);
1496 assert(blob_info->signature == WizardSignature);
1497 p=(const unsigned char *) ReadBlobStream(blob_info,1,buffer,&count);
1498 if (count != 1)
1499 return(EOF);
1500 return((int) (*p));
1501}
1502
1503/*
1504%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1505% %
1506% %
1507% %
1508+ R e a d B l o b C h u n k %
1509% %
1510% %
1511% %
1512%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1513%
1514% ReadBlobChunk() reads data from the blob and returns it. It returns the
1515% number of bytes read. ReadBlobChunk() differs from ReadBlob() by making an
1516% effort to return the number of bytes that was requested except in the event
1517% an EOF is encountered.
1518%
1519% The format of the ReadBlobChunk method is:
1520%
1521% ssize_t ReadBlobChunk(BlobInfo *blob_info,const size_t length,
1522% void *data)
1523%
1524% A description of each parameter follows:
1525%
1526% o blob_info: the blob info.
1527%
1528% o length: the number of bytes to read from the blob.
1529%
1530% o data: the area to place the information requested from the blob.
1531%
1532*/
1533WizardExport ssize_t ReadBlobChunk(BlobInfo *blob_info,const size_t length,
1534 void *data)
1535{
1536 ssize_t
1537 i;
1538
1539 ssize_t
1540 count;
1541
1542 assert(blob_info != (BlobInfo *) NULL);
1543 assert(blob_info->signature == WizardSignature);
1544 assert(blob_info->type != UndefinedStream);
1545 assert(data != (void *) NULL);
1546 if (blob_info->type == BlobStream)
1547 return(ReadBlob(blob_info,length,data));
1548 count=0;
1549 for (i=0; i < (ssize_t) length; i+=count)
1550 {
1551 count=ReadBlob(blob_info,(size_t) WizardMin(length-i,SSIZE_MAX),
1552 (unsigned char *) data+i);
1553 if (count <= 0)
1554 {
1555 count=0;
1556 if (errno != EINTR)
1557 break;
1558 }
1559 }
1560 return(i);
1561}
1562
1563/*
1564%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1565% %
1566% %
1567% %
1568+ S e t B l o b E x t e n t %
1569% %
1570% %
1571% %
1572%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1573%
1574% SetBlobExtent() ensures enough space is allocated for the blob. If the
1575% method is successful, subsequent writes to bytes in the specified range are
1576% guaranteed not to fail.
1577%
1578% The format of the SetBlobExtent method is:
1579%
1580% WizardBooleanType SetBlobExtent(BlobInfo *blob_info,
1581% const WizardSizeType extent)
1582%
1583% A description of each parameter follows:
1584%
1585% o blob_info: the blob info.
1586%
1587% o extent: the blob maximum extent.
1588%
1589*/
1591 const WizardSizeType extent)
1592{
1593 assert(blob_info != (BlobInfo *) NULL);
1594 assert(blob_info->signature == WizardSignature);
1595 switch (blob_info->type)
1596 {
1597 case UndefinedStream:
1598 break;
1599 case StandardStream:
1600 {
1601 return(WizardFalse);
1602 break;
1603 }
1604 case FileStream:
1605 {
1606 ssize_t
1607 count;
1608
1610 offset;
1611
1612 if (extent != (WizardSizeType) ((off_t) extent))
1613 return(WizardFalse);
1614 offset=fseek(blob_info->file_info.file,0,SEEK_END);
1615 if (offset < 0)
1616 return(WizardFalse);
1617 if ((WizardSizeType) offset >= extent)
1618 break;
1619 offset=fseek(blob_info->file_info.file,(WizardOffsetType) extent-1,
1620 SEEK_SET);
1621 if (offset < 0)
1622 break;
1623 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
1624 blob_info->file_info.file);
1625 offset=fseek(blob_info->file_info.file,offset,SEEK_SET);
1626 if (count != 1)
1627 return(WizardFalse);
1628 break;
1629 }
1630 case PipeStream:
1631 case ZipStream:
1632 {
1633 return(WizardFalse);
1634 break;
1635 }
1636 case BZipStream:
1637 return(WizardFalse);
1638 case BlobStream:
1639 {
1640 if (extent != (WizardSizeType) ((size_t) extent))
1641 return(WizardFalse);
1642 if (blob_info->mapped != WizardFalse)
1643 {
1644 ssize_t
1645 count;
1646
1648 offset;
1649
1650 (void) UnmapBlob(blob_info->data,blob_info->length);
1652 if (blob_info->file_info.file == (FILE *) NULL)
1653 return(WizardFalse);
1654 offset=fseek(blob_info->file_info.file,0,SEEK_END);
1655 if (offset < 0)
1656 return(WizardFalse);
1657 if ((WizardSizeType) offset >= extent)
1658 break;
1659 offset=fseek(blob_info->file_info.file,(WizardOffsetType) extent-1,
1660 SEEK_SET);
1661 if (offset < 0)
1662 return(WizardFalse);
1663 count=(ssize_t) fwrite((const unsigned char *) "",1,1,
1664 blob_info->file_info.file);
1665 offset=fseek(blob_info->file_info.file,offset,SEEK_SET);
1666 if (count != 1)
1667 return(WizardFalse);
1668 (void) AcquireWizardResource(MapResource,extent);
1669 blob_info->data=(unsigned char *) MapBlob(fileno(
1670 blob_info->file_info.file),WriteMode,0,(size_t) extent);
1671 blob_info->extent=(size_t) extent;
1672 blob_info->length=(size_t) extent;
1673 (void) SyncBlob(blob_info);
1674 break;
1675 }
1676 blob_info->extent=(size_t) extent;
1677 blob_info->data=(unsigned char *) ResizeQuantumMemory(
1678 blob_info->data,blob_info->extent,sizeof(*blob_info->data));
1679 (void) SyncBlob(blob_info);
1680 if (blob_info->data == (unsigned char *) NULL)
1681 {
1682 (void) DetachBlob(blob_info);
1683 return(WizardFalse);
1684 }
1685 break;
1686 }
1687 }
1688 return(WizardTrue);
1689}
1690
1691/*
1692%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1693% %
1694% %
1695% %
1696% S y n c B l o b %
1697% %
1698% %
1699% %
1700%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1701%
1702% SyncBlob() flushes the datastream if it is a file or synchonizes the data
1703% attributes if it is an blob.
1704%
1705% The format of the SyncBlob method is:
1706%
1707% int SyncBlob(BlobInfo *blob_info)
1708%
1709% A description of each parameter follows:
1710%
1711% o blob_info: the blob info.
1712%
1713*/
1715{
1716 int
1717 status;
1718
1719 assert(blob_info != (BlobInfo *) NULL);
1720 assert(blob_info->signature == WizardSignature);
1721 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",blob_info->filename);
1722 status=0;
1723 switch (blob_info->type)
1724 {
1725 case UndefinedStream:
1726 case StandardStream:
1727 break;
1728 case FileStream:
1729 case PipeStream:
1730 {
1731 status=fflush(blob_info->file_info.file);
1732 break;
1733 }
1734 case ZipStream:
1735 {
1736#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
1737 status=gzflush(blob_info->file_info.gzfile,Z_SYNC_FLUSH);
1738#endif
1739 break;
1740 }
1741 case BZipStream:
1742 {
1743#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
1744 status=BZ2_bzflush(blob_info->file_info.bzfile);
1745#endif
1746 break;
1747 }
1748 case BlobStream:
1749 break;
1750 }
1751 return(status);
1752}
1753
1754/*
1755%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1756% %
1757% %
1758% %
1759+ T e l l B l o b %
1760% %
1761% %
1762% %
1763%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1764%
1765% TellBlob() obtains the current value of the blob or file position.
1766%
1767% The format of the TellBlob method is:
1768%
1769% WizardOffsetType TellBlob(const BlobInfo *blob_info)
1770%
1771% A description of each parameter follows:
1772%
1773% o image: The image.
1774%
1775*/
1777{
1779 offset;
1780
1781 assert(blob_info != (BlobInfo *) NULL);
1782 assert(blob_info->signature == WizardSignature);
1783 assert(blob_info->type != UndefinedStream);
1784 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"%s",blob_info->filename);
1785 offset=(-1);
1786 switch (blob_info->type)
1787 {
1788 case UndefinedStream:
1789 case StandardStream:
1790 break;
1791 case FileStream:
1792 {
1793 offset=ftell(blob_info->file_info.file);
1794 break;
1795 }
1796 case PipeStream:
1797 break;
1798 case ZipStream:
1799 {
1800#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
1801 offset=(WizardOffsetType) gztell(blob_info->file_info.gzfile);
1802#endif
1803 break;
1804 }
1805 case BZipStream:
1806 break;
1807 case BlobStream:
1808 {
1809 offset=blob_info->offset;
1810 break;
1811 }
1812 }
1813 return(offset);
1814}
1815
1816/*
1817%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1818% %
1819% %
1820% %
1821+ U n m a p B l o b %
1822% %
1823% %
1824% %
1825%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1826%
1827% UnmapBlob() deallocates the binary large object previously allocated with
1828% the MapBlob method.
1829%
1830% The format of the UnmapBlob method is:
1831%
1832% WizardBooleanType UnmapBlob(void *map,const size_t length)
1833%
1834% A description of each parameter follows:
1835%
1836% o map: The address of the binary large object.
1837%
1838% o length: The length of the binary large object.
1839%
1840*/
1841WizardExport WizardBooleanType UnmapBlob(void *map,const size_t length)
1842{
1843#if defined(WIZARDSTOOLKIT_HAVE_MMAP_FILEIO)
1844 int
1845 status;
1846
1847 status=munmap(map,length);
1848 return(status == -1 ? WizardFalse : WizardTrue);
1849#else
1850 return(WizardFalse);
1851#endif
1852}
1853
1854/*
1855%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1856% %
1857% %
1858% %
1859+ W r i t e B l o b %
1860% %
1861% %
1862% %
1863%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
1864%
1865% WriteBlob() writes data to a blob or blob_info file. It returns the number
1866% of bytes written.
1867%
1868% The format of the WriteBlob method is:
1869%
1870% ssize_t WriteBlob(BlobInfo *blob_info,const size_t length,
1871% const void *data)
1872%
1873% A description of each parameter follows:
1874%
1875% o blob_info: the blob.
1876%
1877% o length: the number of bytes to write to the blob.
1878%
1879% o data: the area to place the information requested from the blob.
1880%
1881*/
1882WizardExport ssize_t WriteBlob(BlobInfo *blob_info,const size_t length,
1883 const void *data)
1884{
1885 int
1886 c;
1887
1888 const unsigned char
1889 *p;
1890
1891 ssize_t
1892 count;
1893
1894 assert(blob_info != (BlobInfo *) NULL);
1895 assert(blob_info->signature == WizardSignature);
1896 assert(data != (const void *) NULL);
1897 if (length == 0)
1898 return(0);
1899 count=0;
1900 p=(const unsigned char *) data;
1901 switch (blob_info->type)
1902 {
1903 case UndefinedStream:
1904 break;
1905 case StandardStream:
1906 case FileStream:
1907 case PipeStream:
1908 {
1909 switch (length)
1910 {
1911 default:
1912 {
1913 count=(ssize_t) fwrite((const char *) data,1,length,
1914 blob_info->file_info.file);
1915 break;
1916 }
1917 case 4:
1918 {
1919 c=putc((int) *p++,blob_info->file_info.file);
1920 if (c == EOF)
1921 break;
1922 count++;
1923 }
1924 case 3:
1925 {
1926 c=putc((int) *p++,blob_info->file_info.file);
1927 if (c == EOF)
1928 break;
1929 count++;
1930 }
1931 case 2:
1932 {
1933 c=putc((int) *p++,blob_info->file_info.file);
1934 if (c == EOF)
1935 break;
1936 count++;
1937 }
1938 case 1:
1939 {
1940 c=putc((int) *p++,blob_info->file_info.file);
1941 if (c == EOF)
1942 break;
1943 count++;
1944 }
1945 case 0:
1946 break;
1947 }
1948 break;
1949 }
1950 case ZipStream:
1951 {
1952#if defined(WIZARDSTOOLKIT_ZLIB_DELEGATE)
1953 switch (length)
1954 {
1955 default:
1956 {
1957 count=(ssize_t) gzwrite(blob_info->file_info.gzfile,(void *) data,
1958 (unsigned int) length);
1959 break;
1960 }
1961 case 4:
1962 {
1963 c=gzputc(blob_info->file_info.gzfile,(int) *p++);
1964 if (c == EOF)
1965 break;
1966 count++;
1967 }
1968 case 3:
1969 {
1970 c=gzputc(blob_info->file_info.gzfile,(int) *p++);
1971 if (c == EOF)
1972 break;
1973 count++;
1974 }
1975 case 2:
1976 {
1977 c=gzputc(blob_info->file_info.gzfile,(int) *p++);
1978 if (c == EOF)
1979 break;
1980 count++;
1981 }
1982 case 1:
1983 {
1984 c=gzputc(blob_info->file_info.gzfile,(int) *p++);
1985 if (c == EOF)
1986 break;
1987 count++;
1988 }
1989 case 0:
1990 break;
1991 }
1992#endif
1993 break;
1994 }
1995 case BZipStream:
1996 {
1997#if defined(WIZARDSTOOLKIT_BZLIB_DELEGATE)
1998 count=(ssize_t) BZ2_bzwrite(blob_info->file_info.bzfile,(void *) data,
1999 (int) length);
2000#endif
2001 break;
2002 }
2003 case BlobStream:
2004 {
2005 unsigned char
2006 *q;
2007
2008 if ((blob_info->offset+(WizardOffsetType) length) >=
2009 (WizardOffsetType) blob_info->extent)
2010 {
2011 if (blob_info->mapped != WizardFalse)
2012 return(0);
2013 blob_info->quantum<<=1;
2014 blob_info->extent+=length+blob_info->quantum;
2015 blob_info->data=(unsigned char *) ResizeQuantumMemory(
2016 blob_info->data,blob_info->extent+1,sizeof(*blob_info->data));
2017 (void) SyncBlob(blob_info);
2018 if (blob_info->data == (unsigned char *) NULL)
2019 {
2020 (void) DetachBlob(blob_info);
2021 return(0);
2022 }
2023 }
2024 q=blob_info->data+blob_info->offset;
2025 (void) memcpy(q,p,length);
2026 blob_info->offset+=length;
2027 if (blob_info->offset >= (WizardOffsetType) blob_info->length)
2028 blob_info->length=(size_t) blob_info->offset;
2029 count=(ssize_t) length;
2030 }
2031 }
2032 return(count);
2033}
2034
2035/*
2036%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2037% %
2038% %
2039% %
2040+ W r i t e B l o b B y t e %
2041% %
2042% %
2043% %
2044%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2045%
2046% WriteBlobByte() write an integer to a blob. It returns the number of bytes
2047% written (either 0 or 1);
2048%
2049% The format of the WriteBlobByte method is:
2050%
2051% ssize_t WriteBlobByte(BlobInfo *blob_info,const unsigned char value)
2052%
2053% A description of each parameter follows.
2054%
2055% o blob_info: the blob info.
2056%
2057% o value: the value to write.
2058%
2059*/
2060
2061static inline ssize_t WriteBlobStream(BlobInfo *blob_info,const size_t length,
2062 const void *data)
2063{
2064 unsigned char
2065 *q;
2066
2068 extent;
2069
2070 assert(blob_info != (BlobInfo *) NULL);
2071 if (blob_info->type != BlobStream)
2072 return(WriteBlob(blob_info,length,data));
2073 assert(blob_info->type != UndefinedStream);
2074 assert(data != (void *) NULL);
2075 extent=(WizardSizeType) (blob_info->offset+(WizardOffsetType) length);
2076 if (extent >= blob_info->extent)
2077 {
2078 blob_info->quantum<<=1;
2079 extent=blob_info->extent+blob_info->quantum+length;
2080 if (SetBlobExtent(blob_info,extent) == WizardFalse)
2081 return(0);
2082 }
2083 q=blob_info->data+blob_info->offset;
2084 (void) memcpy(q,data,length);
2085 blob_info->offset+=length;
2086 if (blob_info->offset >= (WizardOffsetType) blob_info->length)
2087 blob_info->length=(size_t) blob_info->offset;
2088 return((ssize_t) length);
2089}
2090
2092 const unsigned char value)
2093{
2094 assert(blob_info != (BlobInfo *) NULL);
2095 assert(blob_info->signature == WizardSignature);
2096 return(WriteBlobStream(blob_info,1,&value));
2097}
2098
2099/*
2100%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2101% %
2102% %
2103% %
2104+ W r i t e B l o b C h u n k %
2105% %
2106% %
2107% %
2108%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2109%
2110% WriteBlobChunk() writes data to a blob or blob_info file. It returns the
2111% number of bytes written. WriteBlobChunk() differs from WriteBlob() by
2112% making an effort to write the number of bytes that was requested except in
2113% the event an EOF is encountered.
2114%
2115% The format of the WriteBlob method is:
2116%
2117% ssize_t WriteBlobChunk(BlobInfo *blob_info,const size_t length,
2118% const void *data)
2119%
2120% A description of each parameter follows:
2121%
2122% o blob_info: the blob.
2123%
2124% o length: the number of bytes to write to the blob.
2125%
2126% o data: the area to place the information requested from the blob.
2127%
2128*/
2129WizardExport ssize_t WriteBlobChunk(BlobInfo *blob_info,const size_t length,
2130 const void *data)
2131{
2132 ssize_t
2133 i;
2134
2135 ssize_t
2136 count;
2137
2138 assert(blob_info != (BlobInfo *) NULL);
2139 assert(blob_info->signature == WizardSignature);
2140 assert(data != (const unsigned char *) NULL);
2141 if (blob_info->type == BlobStream)
2142 return(WriteBlob(blob_info,length,data));
2143 count=0;
2144 for (i=0; i < (ssize_t) length; i+=count)
2145 {
2146 count=WriteBlob(blob_info,(size_t) WizardMin(length-i,SSIZE_MAX),
2147 (const unsigned char *) data+i);
2148 if (count <= 0)
2149 {
2150 count=0;
2151 if (errno != EINTR)
2152 break;
2153 }
2154 }
2155 return(i);
2156}
2157
2158/*
2159%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2160% %
2161% %
2162% %
2163+ W r i t e B l o b S t r i n g %
2164% %
2165% %
2166% %
2167%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
2168%
2169% WriteBlobString() write a string to a blob. It returns the number of
2170% characters written.
2171%
2172% The format of the WriteBlobString method is:
2173%
2174% ssize_t WriteBlobString(BlobInfo *blob_info,const char *string)
2175%
2176% A description of each parameter follows.
2177%
2178% o image: The image.
2179%
2180% o string: Specifies the string to write.
2181%
2182*/
2183WizardExport ssize_t WriteBlobString(BlobInfo *blob_info,const char *string)
2184{
2185 ssize_t
2186 count;
2187
2188 assert(blob_info != (BlobInfo *) NULL);
2189 assert(blob_info->signature == WizardSignature);
2190 assert(string != (const char *) NULL);
2191 count=WriteBlobStream(blob_info,strlen(string),(const unsigned char *)
2192 string);
2193 return(count);
2194}
BlobMode
@ ReadBlobMode
@ UndefinedBlobMode
@ WriteBinaryBlobMode
@ ReadBinaryBlobMode
@ WriteBlobMode
WizardExport WizardBooleanType CloseBlob(BlobInfo *blob_info)
Definition blob.c:236
WizardExport WizardSizeType GetBlobSize(BlobInfo *blob_info)
Definition blob.c:800
WizardExport int EOFBlob(BlobInfo *blob_info)
Definition blob.c:471
WizardExport ssize_t ReadBlob(BlobInfo *blob_info, const size_t length, void *data)
Definition blob.c:1286
WizardExport ssize_t WriteBlobChunk(BlobInfo *blob_info, const size_t length, const void *data)
Definition blob.c:2129
WizardExport WizardBooleanType UnmapBlob(void *map, const size_t length)
Definition blob.c:1841
static unsigned char * DetachBlob(BlobInfo *)
Definition blob.c:422
static const void * ReadBlobStream(BlobInfo *blob_info, const size_t length, void *data, ssize_t *count)
Definition blob.c:1460
WizardExport BlobInfo * DestroyBlob(BlobInfo *blob_info)
Definition blob.c:369
WizardExport WizardOffsetType TellBlob(const BlobInfo *blob_info)
Definition blob.c:1776
WizardExport BlobInfo * OpenBlob(const char *filename, const BlobMode mode, const WizardBooleanType compress, ExceptionInfo *exception)
Definition blob.c:1014
WizardExport WizardBooleanType SetBlobExtent(BlobInfo *blob_info, const WizardSizeType extent)
Definition blob.c:1590
WizardExport int SyncBlob(BlobInfo *blob_info)
Definition blob.c:1714
WizardExport ssize_t WriteBlobString(BlobInfo *blob_info, const char *string)
Definition blob.c:2183
#define MAP_FAILED
Definition blob.c:67
StreamType
Definition blob.c:74
@ FileStream
Definition blob.c:77
@ BlobStream
Definition blob.c:81
@ ZipStream
Definition blob.c:79
@ BZipStream
Definition blob.c:80
@ StandardStream
Definition blob.c:76
@ UndefinedStream
Definition blob.c:75
@ PipeStream
Definition blob.c:78
static void ThrowBlobException(BlobInfo *blob_info)
Definition blob.c:229
WizardExport int ReadBlobByte(BlobInfo *blob_info)
Definition blob.c:1484
WizardExport void * FileToBlob(const char *filename, const size_t extent, size_t *length, ExceptionInfo *exception)
Definition blob.c:546
WizardExport ssize_t WriteBlobByte(BlobInfo *blob_info, const unsigned char value)
Definition blob.c:2091
WizardExport ssize_t ReadBlobChunk(BlobInfo *blob_info, const size_t length, void *data)
Definition blob.c:1533
static ssize_t WriteBlobStream(BlobInfo *blob_info, const size_t length, const void *data)
Definition blob.c:2061
WizardExport const struct stat * GetBlobProperties(const BlobInfo *blob_info)
Definition blob.c:882
#define WizardMaxBlobExtent
Definition blob.c:62
static WizardBooleanType GetPathAttributes(const char *path, void *attributes)
Definition blob.c:784
static void AttachBlob(BlobInfo *blob_info, const void *blob, const size_t length)
Definition blob.c:191
WizardExport void * MapBlob(int file, const MapMode mode, const WizardOffsetType offset, const size_t length)
Definition blob.c:920
WizardExport ssize_t WriteBlob(BlobInfo *blob_info, const size_t length, const void *data)
Definition blob.c:1882
WizardExport void GetBlobInfo(BlobInfo *blob_info)
Definition blob.c:748
WizardExport const char * GetBlobFilename(const BlobInfo *blob_info)
Definition blob.c:717
#define WizardMaxBufferExtent
Definition blob.h:28
MapMode
Definition blob.h:32
@ WriteMode
Definition blob.h:34
@ IOMode
Definition blob.h:35
@ ReadMode
Definition blob.h:33
#define MaxCipherBlocksize
Definition cipher.h:27
WizardExport WizardBooleanType ThrowWizardException(ExceptionInfo *exception, const char *module, const char *function, const size_t line, const ExceptionType severity, const char *format,...)
Definition exception.c:1029
@ BlobError
Definition exception.h:100
@ ResourceError
Definition exception.h:101
WizardBooleanType LogWizardEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition log.c:1390
WizardExport WizardBooleanType IsEventLogging(void)
Definition log.c:688
@ TraceEvent
Definition log.h:39
@ BlobEvent
Definition log.h:41
#define GetWizardModule()
Definition log.h:30
WizardExport void * AcquireWizardMemory(const size_t size)
Definition memory.c:586
WizardExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition memory.c:657
WizardExport void * RelinquishWizardMemory(void *memory)
Definition memory.c:1039
WizardExport void * ResizeQuantumMemory(void *memory, const size_t count, const size_t quantum)
Definition memory.c:1236
#define WizardExport
#define WizardPathExtent
#define WizardSignature
WizardExport WizardBooleanType AcquireWizardResource(const ResourceType type, const WizardSizeType size)
Definition resource.c:388
WizardExport void RelinquishWizardResource(const ResourceType type, const WizardSizeType size)
Definition resource.c:746
@ MapResource
Definition resource_.h:38
WizardExport void RelinquishSemaphoreInfo(SemaphoreInfo **semaphore_info)
Definition semaphore.c:338
WizardExport SemaphoreInfo * AcquireSemaphoreInfo(void)
Definition semaphore.c:156
WizardExport void LockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition semaphore.c:282
WizardExport void UnlockSemaphoreInfo(SemaphoreInfo *semaphore_info)
Definition semaphore.c:437
static long StringToLong(const char *value)
WizardExport int LocaleNCompare(const char *p, const char *q, const size_t length)
Definition string.c:1608
WizardExport int LocaleCompare(const char *p, const char *q)
Definition string.c:1510
WizardExport size_t CopyWizardString(char *destination, const char *source, const size_t length)
Definition string.c:762
int error
Definition blob.c:118
WizardBooleanType eof
Definition blob.c:115
WizardOffsetType offset
Definition blob.c:122
char filename[WizardPathExtent]
Definition blob.c:103
WizardBooleanType temporary
Definition blob.c:129
ssize_t reference_count
Definition blob.c:153
size_t length
Definition blob.c:106
SemaphoreInfo * semaphore
Definition blob.c:150
int error_number
Definition blob.c:119
StreamType type
Definition blob.c:135
unsigned char * data
Definition blob.c:144
WizardSizeType size
Definition blob.c:125
size_t signature
Definition blob.c:156
WizardBooleanType mapped
Definition blob.c:114
size_t extent
Definition blob.c:107
int status
Definition blob.c:132
WizardBooleanType debug
Definition blob.c:147
size_t quantum
Definition blob.c:108
BlobFileInfo file_info
Definition blob.c:138
struct stat properties
Definition blob.c:140
BlobMode mode
Definition blob.c:111
WizardBooleanType exempt
Definition blob.c:128
#define Min(x, y)
Definition studio.h:307
#define O_BINARY
Definition studio.h:326
FILE * file
Definition blob.c:87
static int open_utf8(const char *path, int flags, mode_t mode)
#define WizardMin(x, y)
static FILE * fopen_utf8(const char *path, const char *mode)
static int stat_utf8(const char *path, struct stat *attributes)
static FILE * popen_utf8(const char *command, const char *type)
WizardExport void GetPathComponent(const char *path, PathType type, char *component)
Definition utility.c:415
@ ExtensionPath
Definition utility.h:33
size_t WizardSizeType
Definition wizard-type.h:51
ssize_t WizardOffsetType
Definition wizard-type.h:50
WizardBooleanType
Definition wizard-type.h:26
@ WizardTrue
Definition wizard-type.h:28
@ WizardFalse
Definition wizard-type.h:27