2 * Copyright (c) 2000-2001 Apple Computer, Inc. All Rights Reserved.
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
20 // AtomicFile.h - Description t.b.d.
25 #include <Security/threading.h>
30 #if _USE_IO == _USE_IO_POSIX
31 #include <sys/types.h>
32 #include <machine/endian.h>
33 #elif _USE_IO == _USE_IO_MACOS
38 #ifdef _CPP_ATOMICFILE
51 typedef int VersionId
;
53 AtomicFile(const DbName
&inDbName
);
56 // Close the currently open AtomicFile. (If there are transactions outstanding this call
57 // has no effect until after they have completed.
60 // Start a read operation. Returns a mmaped region with the file in it. Return the size of the
61 // file in length. Each call to enterRead() *must* be paired with a call to exitRead.
62 VersionId
enterRead(const uint8
*&outFileAddress
, size_t &outLength
);
64 // End a read operation.
65 void exitRead(VersionId inVersionId
);
67 // Return true if inVersionId is not the most recent version of this file.
68 bool isDirty(VersionId inVersionId
);
70 // Aquire the write lock and remove the file.
73 // Create and lock the database file for writing, and set outWriteRef to a newly created
74 // file open for writing.
75 // Return the new VersionId this file will have after a succesful commit.
76 VersionId
enterCreate(FileRef
&outWriteRef
);
78 // Lock the database file for writing, map the database file for reading and
79 // set outWriteRef to a newly created file open for writing.
80 // Return the VersionId or the file being modified.
81 VersionId
enterWrite(const uint8
*&outFileAddress
, size_t &outLength
, FileRef
&outWriteRef
);
83 // Commit the current create or write and close the write file. Return the VersionId of the new file.
86 // Rollback the current create or write.
95 void write(OffsetType inOffsetType
, uint32 inOffset
, const uint32
*inData
, uint32 inCount
);
96 void write(OffsetType inOffsetType
, uint32 inOffset
, const uint8
*inData
, uint32 inLength
);
97 void write(OffsetType inOffsetType
, uint32 inOffset
, const uint32 inData
);
98 const string
filename() const { return mReadFilename
; }
101 void rename(const string
&inSrcFilename
, const string
&inDestFilename
);
102 void unlink(const string
&inFilename
);
107 OpenFile(const std::string
&inFilename
, bool write
, bool lock
, VersionId inVersionId
, mode_t mode
);
111 VersionId
versionId() const { return mVersionId
; }
112 FileRef
fileRef() const { return mFileRef
; }
113 const uint8
*address() const { return mAddress
; }
114 size_t length() const { return mLength
; }
116 // Check if the file has its dirty bit set.
118 // Set the files dirty bit (requires the file to be writeable and locked).
124 // Return the mode bits of the file
130 VersionId
readVersionId();
131 void writeVersionId(VersionId inVersionId
);
132 static void mkpath(const std::string
&inFilename
);
134 VersionId mVersionId
;
135 const uint8
*mAddress
;
150 string mReadFilename
;
153 OpenFile
*mWriteFile
;
154 string mWriteFilename
;
156 typedef std::map
<VersionId
, OpenFile
*> OpenFileMap
;
157 OpenFileMap mOpenFileMap
;
166 virtual ~AtomicFileRef();
168 uint32
at(uint32 inOffset
)
170 return ntohl(*reinterpret_cast<const uint32
*>(mAddress
+ inOffset
));
173 uint32
operator[](uint32 inOffset
)
175 if (inOffset
+ sizeof(uint32
) > mLength
)
176 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT
);
180 const uint8
*range(uint32 inOffset
, uint32 inLength
)
182 if (inOffset
+ inLength
> mLength
)
183 CssmError::throwMe(CSSMERR_DL_DATABASE_CORRUPT
);
184 return mAddress
+ inOffset
;
187 const AtomicFile::VersionId mVersionId
;
190 AtomicFileRef(AtomicFile
&inAtomicFile
, const InitArg
&inInitArg
);
192 AtomicFile
&mAtomicFile
;
193 const uint8
*mAddress
;
194 const size_t mLength
;
197 // Use this class to open an AtomicFile for reading.
198 class AtomicFileReadRef
: public AtomicFileRef
201 AtomicFileReadRef(AtomicFile
&inAtomicFile
);
202 virtual ~AtomicFileReadRef();
204 static InitArg
enterRead(AtomicFile
&inAtomicFile
);
207 // Use this class to open an AtomicFile for writing.
208 class AtomicFileWriteRef
: public AtomicFileRef
211 AtomicFileWriteRef(AtomicFile
&inAtomicFile
);
212 virtual ~AtomicFileWriteRef();
213 AtomicFile::VersionId
commit() { mOpen
= false; return mAtomicFile
.commit(); }
216 static InitArg
enterWrite(AtomicFile
&inAtomicFile
, AtomicFile::FileRef
&outWriteFileRef
);
217 AtomicFile::FileRef mFileRef
;
221 } // end namespace Security
223 #ifdef _CPP_ATOMICFILE
227 #endif //_H_ATOMICFILE