reindent-20030715
[openafs.git] / src / JAVA / libjafs / FileOutputStream.c
1 /*
2  * Copyright (c) 2001-2002 International Business Machines Corp.
3  * All rights reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  * 
9  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
10  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
11  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
12  * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR
13  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
14  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
15  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
16  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
17  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
18  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
19  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
20  */
21
22 #include <afs/param.h>
23 #include <errno.h>
24
25 #include "Internal.h"
26 #include "org_openafs_jafs_FileOutputStream.h"
27
28 #include <stdio.h>
29 #include <fcntl.h>
30 /*#include <afs/afs_usrops.h>*/
31
32 #ifdef DMALLOC
33 #include "dmalloc.h"
34 #endif
35
36 /**
37  * Be carefull with the memory management:
38  *
39  * - For every getNativeString call the corresponding free().
40  * - For every Get<type>ArrayElements call the corresponding
41  *   Release<type>ArrayElements
42  * - For every malloc call the corresponding free.
43  */
44
45 /*-------------------------------------------------------------------------*/
46
47 /**
48  * Opens an AFS file, with the specified name, for appending.
49  * 
50  *  env         the Java environment
51  *  obj         the current Java object
52  *  fileNameUTF name of file to be opened
53  *
54  * @returns             file descriptor
55  * @exception   AFSFileException  if an I/O or other file related error occurs.
56  */
57 JNIEXPORT jint JNICALL
58 Java_org_openafs_jafs_FileOutputStream_openWrite(JNIEnv * env, jobject obj,
59                                                  jstring fileNameUTF)
60 {
61     int err;
62     jint fd = -1;               //file descriptor
63
64     fd = openAFSFile(env, fileNameUTF, O_CREAT | O_TRUNC, 0644, &err);
65     if (fd < 0) {
66         fprintf(stderr, "FileOutputStream::openWrite(): err=%d\n", err);
67         throwAFSFileException(env, err, NULL);
68     }
69     return fd;
70 }
71
72 /**
73  * Opens an AFS file, with the specified name, for writing.
74  * 
75  *  env         the Java environment
76  *  obj         the current Java object
77  *  fileNameUTF name of file to be opened
78  *
79  * @return              file descriptor
80  * @exception   AFSFileException  if an I/O or other file related error occurs.
81  */
82 JNIEXPORT jint JNICALL
83 Java_org_openafs_jafs_FileOutputStream_openAppend(JNIEnv * env, jobject obj,
84                                                   jstring fileNameUTF)
85 {
86     int err;
87     jint fd = -1;               //file descriptor
88
89     fd = openAFSFile(env, fileNameUTF, O_CREAT | O_APPEND, 0644, &err);
90     if (fd < 0) {
91         fprintf(stderr, "FileOutputStream::openAppend(): err=%d\n", err);
92         throwAFSFileException(env, err, NULL);
93     }
94     return fd;
95 }
96
97 /**
98  * Writes 'lenght' bytes from the specified byte array starting at offset 
99  * 'offset' to this file output stream. 
100  * 
101  *  env         the Java environment
102  *  obj         the current Java object
103  *  jbytes              the data to be written
104  *  offset              the start offset in the data
105  *  length              the number of bytes that are written
106  *
107  * @exception   AFSFileException  if an I/O or other file related error occurs.
108  */
109 JNIEXPORT void JNICALL
110 Java_org_openafs_jafs_FileOutputStream_write(JNIEnv * env, jobject obj,
111                                              jbyteArray jbytes, jint offset,
112                                              jint length)
113 {
114     int fd, written, toWrite;
115     jint twritten;
116     jclass thisClass;
117     jmethodID getFileDescriptorID;
118     char *bytes;
119     jfieldID fid;
120
121     thisClass = (*env)->GetObjectClass(env, obj);
122     fid = (*env)->GetFieldID(env, thisClass, "fileDescriptor", "I");
123     fd = (*env)->GetIntField(env, obj, fid);
124     if (fd < 0) {
125         fprintf(stderr, "FileOutputStream::write(): failed to get file 
126                        descriptor\n");
127         throwAFSFileException(env, 0, "Failed to get file descriptor!");
128     }
129
130     bytes = (char *)malloc(length);
131     if (bytes == NULL) {
132         fprintf(stderr,
133                 "FileOutputStream::write(): malloc failed of %d bytes\n",
134                 length);
135         throwAFSFileException(env, 0, "Failed to allocate memory!");
136     }
137
138     (*env)->GetByteArrayRegion(env, jbytes, offset, length, bytes);
139     toWrite = length;
140     twritten = 0;
141
142     while (toWrite > 0) {
143         written = uafs_write(fd, bytes, length);
144         twritten += written;
145         if (written < 0) {
146             free(bytes);
147             throwAFSFileException(env, errno, NULL);
148         }
149         toWrite -= written;
150     }
151     free(bytes);
152 }
153
154 /**
155  * Closes this file output stream and releases any system resources 
156  * associated with this stream. This file output stream may no longer 
157  * be used for writing bytes. 
158  * 
159  *  env         the Java environment
160  *  obj         the current Java object
161  *
162  * @exception   AFSFileException  if an I/O or other file related error occurs.
163  */
164 JNIEXPORT void JNICALL
165 Java_org_openafs_jafs_FileOutputStream_close(JNIEnv * env, jobject obj)
166 {
167     int fd, rc;
168     jclass thisClass;
169     jmethodID getFileDescriptorID;
170     char *bytes;
171     jfieldID fid;
172
173     thisClass = (*env)->GetObjectClass(env, obj);
174     fid = (*env)->GetFieldID(env, thisClass, "fileDescriptor", "I");
175     fd = (*env)->GetIntField(env, obj, fid);
176     if (fd < 0) {
177         fprintf(stderr,
178                 "FileOutputStream::close(): failed to get file descriptor\n");
179         throwAFSFileException(env, 0, "Failed to get file descriptor!");
180     }
181     rc = uafs_close(fd);
182     if (rc != 0) {
183         throwAFSFileException(env, rc, NULL);
184     }
185 }