e728da1c960ef64e97e58acf5f6b98a097217205
[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 GetStringUTFChars call the corresponding ReleaseStringUTFChars.
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 Java_org_openafs_jafs_FileOutputStream_openWrite
58   (JNIEnv *env, jobject obj, jstring fileNameUTF)
59 {
60   int err;
61   jint fd = -1;         //file descriptor
62
63   fd = openAFSFile(env, fileNameUTF, O_CREAT | O_TRUNC, 0644, &err);
64   if (fd < 0) {
65     fprintf(stderr, "FileOutputStream::openWrite(): err=%d\n", err);
66     throwAFSFileException(env, err, NULL);
67   }
68   return fd;
69 }
70
71 /**
72  * Opens an AFS file, with the specified name, for writing.
73  * 
74  *  env         the Java environment
75  *  obj         the current Java object
76  *  fileNameUTF name of file to be opened
77  *
78  * @return              file descriptor
79  * @exception   AFSFileException  if an I/O or other file related error occurs.
80  */
81 JNIEXPORT jint JNICALL Java_org_openafs_jafs_FileOutputStream_openAppend
82   (JNIEnv *env, jobject obj, jstring fileNameUTF)
83 {
84   int err;
85   jint fd = -1;         //file descriptor
86
87   fd = openAFSFile(env, fileNameUTF, O_CREAT | O_APPEND, 0644, &err);
88   if (fd < 0) {
89     fprintf(stderr, "FileOutputStream::openAppend(): err=%d\n", err);
90     throwAFSFileException(env, err, NULL);
91   }
92   return fd;
93 }
94
95 /**
96  * Writes 'lenght' bytes from the specified byte array starting at offset 
97  * 'offset' to this file output stream. 
98  * 
99  *  env         the Java environment
100  *  obj         the current Java object
101  *  jbytes              the data to be written
102  *  offset              the start offset in the data
103  *  length              the number of bytes that are written
104  *
105  * @exception   AFSFileException  if an I/O or other file related error occurs.
106  */
107 JNIEXPORT void JNICALL Java_org_openafs_jafs_FileOutputStream_write
108   (JNIEnv *env, jobject obj, jbyteArray jbytes, jint offset, jint length)
109 {
110     int fd, written, toWrite;
111     jint twritten;
112     jclass thisClass;
113     jmethodID getFileDescriptorID;
114     char *bytes;
115     jfieldID fid;
116
117     thisClass = (*env)->GetObjectClass(env, obj);
118     fid = (*env)->GetFieldID(env, thisClass, "fileDescriptor", "I");
119     fd = (*env)->GetIntField(env, obj, fid);
120     if(fd < 0) {
121       fprintf(stderr, "FileOutputStream::write(): failed to get file "
122                        "descriptor\n");
123       throwAFSFileException(env, 0, "Failed to get file descriptor!");
124     }
125     bytes = (char*) malloc(length);
126     if(bytes == NULL) {
127       fprintf(stderr, "FileOutputStream::write(): malloc failed of %d bytes\n",
128                        length);
129       throwAFSFileException(env, 0, "Failed to allocate memory!");
130     }
131     (*env) -> GetByteArrayRegion(env, jbytes, offset, length, bytes);
132     toWrite = length;
133     twritten = 0;
134     while(toWrite>0) {
135       written = uafs_write(fd, bytes, length);
136       twritten += written;
137       if(written<0) {
138         free(bytes);
139         throwAFSFileException(env, errno, NULL);
140       }
141       toWrite -= written;
142     }
143     free(bytes);
144 }
145
146 /**
147  * Closes this file output stream and releases any system resources 
148  * associated with this stream. This file output stream may no longer 
149  * be used for writing bytes. 
150  * 
151  *  env         the Java environment
152  *  obj         the current Java object
153  *
154  * @exception   AFSFileException  if an I/O or other file related error occurs.
155  */
156 JNIEXPORT void JNICALL Java_org_openafs_jafs_FileOutputStream_close
157   (JNIEnv *env, jobject obj)
158 {
159     int fd, rc;
160     jclass thisClass;
161     jmethodID getFileDescriptorID;
162     char *bytes;
163     jfieldID fid;
164
165     thisClass = (*env)->GetObjectClass(env, obj);
166     fid = (*env)->GetFieldID(env, thisClass, "fileDescriptor", "I");
167     fd = (*env)->GetIntField(env, obj, fid);
168     if(fd < 0) {
169       fprintf(stderr, "FileOutputStream::close(): failed to get file descriptor\n");
170       throwAFSFileException(env, 0, "Failed to get file descriptor!");
171     }
172     rc = uafs_close(fd);
173     if (rc != 0) {
174       throwAFSFileException(env, rc, NULL);
175     }
176 }
177
178