1 /*
2 cmap_open.c: Opening CCP4-format map files.
3 Copyright (C) 2001 CCLRC, Charles Ballard
4
5 This library is free software: you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public License
7 version 3, modified in accordance with the provisions of the
8 license to address the requirements of UK law.
9
10 You should have received a copy of the modified GNU Lesser General
11 Public License along with this library. If not, copies may be
12 downloaded from http://www.ccp4.ac.uk/ccp4license.php
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU Lesser General Public License for more details.
18 */
19
20 /** @file cmap_open.c
21 *
22 * @brief Opening CCP4-format map files.
23 *
24 * @author Charles Ballard
25 */
26
27 #include <string.h>
28 #include <math.h>
29 #include <stdarg.h>
30 #include <fcntl.h>
31 #include "cmaplib.h"
32 #include "cmap_header.h"
33 #include "cmap_labels.h"
34 #include "cmap_errno.h"
35
36 /*! Internal: malloc CMMFile struct for reading into
37 \return CMMFile */
init_cmap_read(void)38 CMMFile *init_cmap_read(void)
39 {
40 CMMFile *mfile = (CMMFile *) malloc(sizeof(CMMFile));
41 if (mfile)
42 memset(mfile,'\0',sizeof(CMMFile));
43 return mfile;
44 }
45
46 /*! Internal: malloc CMMFile struct for writing
47 \return CMMFile */
init_cmap_write(void)48 CMMFile *init_cmap_write(void)
49 {
50 CMMFile *mfile = (CMMFile *) malloc(sizeof(CMMFile));
51 if (mfile) {
52 memset(mfile,'\0',sizeof(CMMFile));
53 mfile->data_mode = DEFMODE;
54 mfile->symop.offset = 1024U;
55 mfile->data.offset = 1024U; }
56 return mfile;
57 }
58
59 /*! Internal: Identify file as a ccp4 format map
60 \param file The (CCP4File *) struct representing the file.
61 \return non-zero on true, 0 on false */
is_cmap(CCP4File * file)62 int is_cmap(CCP4File *file)
63 {
64 char buffer[4];
65 const unsigned int map_offset = 208U;
66 if (file == NULL)
67 return 0;
68 if ( ccp4_file_raw_seek(file,map_offset,SEEK_SET) == EOF)
69 return 0;
70 if (ccp4_file_readchar(file,(uint8 *) buffer,4U) != 4U)
71 return 0;
72 ccp4_file_rewind(file);
73 return !strncmp(buffer,"MAP ",4);
74 }
75
76 /*! The file is opened.
77 \param filename (char *) the filename
78 \param mode (int) the i/o mode , possible values are O_RDONLY, O_WRONLY,
79 O_RDWR, O_APPEND, O_TMP, O_CREAT, O_TRUNC - see ccp4_sysdep.h
80 \return (void *) CMMFile structure */
ccp4_cmap_open(const char * filename,int mode)81 void *ccp4_cmap_open(const char *filename, int mode)
82 {
83 CMMFile *mfile;
84 CCP4File *cfile;
85 const size_t stamp_offset = 212U;
86
87 if ((cfile = ccp4_file_open(filename, mode)) == NULL) {
88 ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_CantOpenFile),
89 "ccp4_cmap_open",NULL);
90 return (NULL); }
91 ccp4_file_raw_setstamp(cfile, stamp_offset);
92 /* read or write only */
93 if (cfile->read) {
94 if (!is_cmap(cfile) || cfile->length < 1025) {
95 ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_NoHeader),
96 "ccp4_cmap_open",NULL);
97 ccp4_file_close(cfile);
98 return NULL; }
99 ccp4_file_rarch(cfile);
100 mfile = init_cmap_read();
101 mfile->stream = cfile;
102 mfile->file_name = cfile->name;
103 parse_mapheader(mfile);
104 parse_maplabels(mfile);
105 } else if (cfile->write) {
106 mfile = init_cmap_write();
107 mfile->stream = cfile;
108 mfile->file_name = cfile->name;
109 write_mapheader(mfile);
110 write_maplabels(mfile);
111 } else {
112 ccp4_signal( CCP4_ERRLEVEL(3) | CMAP_ERRNO(CMERR_CantOpenFile),
113 "ccp4_cmap_open",NULL);
114 return (NULL); }
115 return (mfile);
116 }
117
118