1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is Mozilla Communicator.
16 * The Initial Developer of the Original Code is
18 * Portions created by the Initial Developer are Copyright (C) 1999
19 * the Initial Developer. All Rights Reserved.
22 * James L. Nance <jim_nance@yahoo.com>
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
46 PRUint32 fsize
; /* The size of the file */
47 PRUint32 msize
; /* The size of the mmap()ed area */
48 PRInt32 pos
; /* Our logical position for doing I/O */
49 char *addr
; /* The base address of our mapping */
50 PRBool needSeek
; /* Do we need to seek to pos before doing a write() */
53 PRStatus
mmio_FileSeek(MmioFile
*mmio
, PRInt32 offset
, PRSeekWhence whence
)
55 mmio
->needSeek
= PR_TRUE
;
62 mmio
->pos
= mmio
->fsize
+ offset
;
65 mmio
->pos
= mmio
->pos
+ offset
;
78 PRInt32
mmio_FileRead(MmioFile
*mmio
, char *dest
, PRInt32 count
)
80 static PRFileMapProtect prot
= PR_PROT_READONLY
;
81 static PRInt64 fsize_l
;
83 /* First see if we are going to try and read past the end of the file
84 * and shorten count if we are.
86 if(mmio
->pos
+count
> mmio
->fsize
) {
87 count
= mmio
->fsize
- mmio
->pos
;
94 /* Check to see if we need to remap for this read */
95 if(mmio
->pos
+count
> mmio
->msize
) {
96 if(mmio
->addr
&& mmio
->msize
) {
97 PR_ASSERT(mmio
->fileMap
);
98 PR_MemUnmap(mmio
->addr
, mmio
->msize
);
99 PR_CloseFileMap(mmio
->fileMap
);
104 LL_UI2L(fsize_l
, mmio
->fsize
);
105 mmio
->fileMap
= PR_CreateFileMap(mmio
->fd
, fsize_l
, prot
);
111 mmio
->addr
= PR_MemMap(mmio
->fileMap
, 0, fsize_l
);
117 mmio
->msize
= mmio
->fsize
;
120 memcpy(dest
, mmio
->addr
+mmio
->pos
, count
);
123 mmio
->needSeek
= PR_TRUE
;
128 PRInt32
mmio_FileWrite(MmioFile
*mmio
, const char *src
, PRInt32 count
)
133 PR_Seek(mmio
->fd
, mmio
->pos
, PR_SEEK_SET
);
134 mmio
->needSeek
= PR_FALSE
;
137 /* If this system does not keep mmap() and write() synchronized, we can
138 ** force it to by doing an munmap() when we do a write. This will
139 ** obviously slow things down but fortunatly we do not do that many
140 ** writes from within mozilla. Platforms which need this may want to
141 ** use the new USE_BUFFERED_REGISTRY_IO code instead of this code though.
143 #if MMAP_MISSES_WRITES
144 if(mmio
->addr
&& mmio
->msize
) {
145 PR_ASSERT(mmio
->fileMap
);
146 PR_MemUnmap(mmio
->addr
, mmio
->msize
);
147 PR_CloseFileMap(mmio
->fileMap
);
153 wcode
= PR_Write(mmio
->fd
, src
, count
);
157 if(mmio
->pos
>mmio
->fsize
) {
158 mmio
->fsize
=mmio
->pos
;
165 PRInt32
mmio_FileTell(MmioFile
*mmio
)
170 PRStatus
mmio_FileClose(MmioFile
*mmio
)
172 if(mmio
->addr
&& mmio
->msize
) {
173 PR_ASSERT(mmio
->fileMap
);
174 PR_MemUnmap(mmio
->addr
, mmio
->msize
);
175 PR_CloseFileMap(mmio
->fileMap
);
180 memset(mmio
, 0, sizeof(*mmio
)); /* Catch people who try to keep using it */
187 MmioFile
*mmio_FileOpen(char *path
, PRIntn flags
, PRIntn mode
)
189 PRFileDesc
*fd
= PR_Open(path
, flags
, mode
);
197 mmio
= PR_MALLOC(sizeof(MmioFile
));
199 if(!mmio
|| PR_FAILURE
==PR_GetOpenFileInfo(fd
, &info
)) {
205 mmio
->fileMap
= NULL
;
206 mmio
->fsize
= info
.size
;
210 mmio
->needSeek
= PR_FALSE
;