Add GNU LGPL headers to all .c .C and .h files
[oweals/cde.git] / cde / programs / nsgmls / StdioStorage.C
1 /*
2  * CDE - Common Desktop Environment
3  *
4  * Copyright (c) 1993-2012, The Open Group. All rights reserved.
5  *
6  * These libraries and programs are free software; you can
7  * redistribute them and/or modify them under the terms of the GNU
8  * Lesser General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * These libraries and programs are distributed in the hope that
13  * they will be useful, but WITHOUT ANY WARRANTY; without even the
14  * implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  * PURPOSE. See the GNU Lesser General Public License for more
16  * details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with these librararies and programs; if not, write
20  * to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
21  * Floor, Boston, MA 02110-1301 USA
22  */
23 /* $XConsortium: StdioStorage.C /main/1 1996/07/29 17:04:42 cde-hp $ */
24 // Copyright (c) 1994, 1995 James Clark
25 // See the file COPYING for copying permission.
26
27 #ifdef __GNUG__
28 #pragma implementation
29 #endif
30
31 #include "splib.h"
32 #include "StdioStorage.h"
33 #include "Message.h"
34 #include "types.h"
35 #include "ErrnoMessageArg.h"
36 #include "StringOf.h"
37 #include "StringC.h"
38 #include "CodingSystem.h"
39
40 #include "StdioStorageMessages.h"
41
42 #include <stdio.h>
43 #include <string.h>
44 #include <stddef.h>
45 #include <errno.h>
46
47 #ifndef SEEK_SET
48 #define SEEK_SET 0
49 #endif
50
51 #ifdef SP_NAMESPACE
52 namespace SP_NAMESPACE {
53 #endif
54
55 class StdioStorageObject : public StorageObject {
56 public:
57   StdioStorageObject(FILE *fp, const StringC &filename);
58   ~StdioStorageObject();
59   Boolean read(char *buf, size_t bufSize, Messenger &mgr, size_t &nread);
60   Boolean rewind(Messenger &mgr);
61   size_t getBlockSize() const;
62 private:
63   enum ErrorIndex {
64     invalidErrorIndex,
65     fopenFailed,
66     readError,
67     seekError
68   };
69   void error(Messenger &mgr, const MessageType2 &, int err);
70
71   FILE *fp_;
72   StringC filename_;
73   String<char> filenameBytes_;
74 };
75
76 StdioStorageManager::StdioStorageManager(const char *type,
77                                          const UnivCharsetDesc &filenameCharset,
78                                          const OutputCodingSystem *filenameCodingSystem)
79 : IdStorageManager(filenameCharset),
80   type_(type),
81   filenameCodingSystem_(filenameCodingSystem)
82 {
83 }
84
85 StorageObject *StdioStorageManager::makeStorageObject(const StringC &str,
86                                                       const StringC &,
87                                                       Boolean,
88                                                       Boolean,
89                                                       Messenger &mgr,
90                                                       StringC &filename)
91 {
92   filename = str;
93   String<char> filenameBytes = filenameCodingSystem_->convertOut(filename);
94   errno = 0;
95   FILE *fp = fopen(filenameBytes.data(), "r");
96   if (!fp) {
97     ParentLocationMessenger(mgr).message(StdioStorageMessages::openFailed,
98                                          StringMessageArg(filename),
99                                          ErrnoMessageArg(errno));
100
101     return 0;
102   }
103   return new StdioStorageObject(fp, filename);
104 }
105
106 const char *StdioStorageManager::type() const
107 {
108   return type_;
109 }
110
111 StdioStorageObject::StdioStorageObject(FILE *fp, const StringC &filename)
112 : fp_(fp), filename_(filename)
113 {
114 }
115
116 StdioStorageObject::~StdioStorageObject()
117 {
118   if (fp_) {
119     fclose(fp_);
120     fp_ = 0;
121   }
122 }
123
124 Boolean StdioStorageObject::rewind(Messenger &mgr)
125 {
126   if (fp_) {
127     errno = 0;
128     if (fseek(fp_, 0L, SEEK_SET) < 0) {
129       error(mgr, StdioStorageMessages::seekFailed, errno);
130       return 0;
131     }
132     return 1;
133   }
134   return 1;
135 }
136
137 size_t StdioStorageObject::getBlockSize() const
138 {
139   return BUFSIZ;
140 }
141
142 Boolean StdioStorageObject::read(char *buf, size_t bufSize, Messenger &mgr,
143                                  size_t &nread)
144 {
145   if (!fp_)
146     return 0;
147   errno = 0;
148   size_t n = 0;
149   FILE *fp = fp_;
150   while (n < bufSize) {
151     int c = getc(fp);
152     if (c == EOF) {
153       if (ferror(fp)) {
154         error(mgr, StdioStorageMessages::readFailed, errno);
155         (void)fclose(fp);
156         return 0;
157       }
158       fclose(fp);
159       fp_ = 0;
160       break;
161     }
162     buf[n++] = c;
163   }
164   nread = n;
165   return n > 0;
166 }
167
168 void StdioStorageObject::error(Messenger &mgr,
169                                const MessageType2 &msg,
170                                int err)
171 {
172   ParentLocationMessenger(mgr).message(msg,
173                                        StringMessageArg(filename_),
174                                        ErrnoMessageArg(err));
175 }
176
177 #ifdef SP_NAMESPACE
178 }
179 #endif