* Merged in jbm's changes for Linux compatibility, fixing Mac compatibility in the process :)
* Fixed two regressions having to do with the _previousTrailerPosition in VersionDictionary.cpp.
* Made sure RTTI is enabled in the OttomanTest target because gtest requires it.
1.1 --- a/Ottoman.xcodeproj/project.pbxproj Mon Sep 28 23:39:08 2009 -0700
1.2 +++ b/Ottoman.xcodeproj/project.pbxproj Tue Sep 29 15:46:42 2009 -0700
1.3 @@ -409,6 +409,7 @@
1.4 ALWAYS_SEARCH_USER_PATHS = NO;
1.5 COPY_PHASE_STRIP = NO;
1.6 GCC_DYNAMIC_NO_PIC = NO;
1.7 + GCC_ENABLE_CPP_RTTI = YES;
1.8 GCC_ENABLE_FIX_AND_CONTINUE = YES;
1.9 GCC_MODEL_TUNING = G5;
1.10 GCC_OPTIMIZATION_LEVEL = 0;
1.11 @@ -423,6 +424,7 @@
1.12 buildSettings = {
1.13 ALWAYS_SEARCH_USER_PATHS = NO;
1.14 DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
1.15 + GCC_ENABLE_CPP_RTTI = YES;
1.16 GCC_MODEL_TUNING = G5;
1.17 INSTALL_PATH = /usr/local/bin;
1.18 PRODUCT_NAME = OttomanTest;
1.19 @@ -434,6 +436,7 @@
1.20 buildSettings = {
1.21 ARCHS = "$(ARCHS_STANDARD_32_BIT)";
1.22 GCC_C_LANGUAGE_STANDARD = c99;
1.23 + GCC_ENABLE_CPP_RTTI = NO;
1.24 GCC_INLINES_ARE_PRIVATE_EXTERN = YES;
1.25 GCC_OPTIMIZATION_LEVEL = 0;
1.26 GCC_PRECOMPILE_PREFIX_HEADER = YES;
2.1 --- a/include/Base.h Mon Sep 28 23:39:08 2009 -0700
2.2 +++ b/include/Base.h Tue Sep 29 15:46:42 2009 -0700
2.3 @@ -13,17 +13,8 @@
2.4 #include <stdint.h>
2.5 #include <string.h>
2.6
2.7 -#if OSX
2.8 -/* OS X specific bits */
2.9 -#include <libkern/OSByteOrder.h>
2.10 +#ifdef __MACH__ /* OS X specific bits */
2.11 #include <CoreFoundation/CFByteOrder.h>
2.12 -
2.13 -#else
2.14 -/* OS X fixup kludge bits */
2.15 -
2.16 -#include <cf_fixup.h>
2.17 -#include <stdint.h>
2.18 -
2.19 #endif
2.20
2.21 namespace Mooseyard {
2.22 @@ -105,7 +96,8 @@
2.23 _value = p._value;
2.24 return *this;
2.25 }
2.26 -
2.27 +
2.28 +#ifdef __COREFOUNDATION_CFBYTEORDER__
2.29 template <> inline uint32_t LittleEndian<uint32_t>::makeLittle (uint32_t i)
2.30 {return OSSwapHostToLittleInt32(i);}
2.31 template <> inline uint32_t LittleEndian<uint32_t>::makeNative (uint32_t i)
2.32 @@ -118,7 +110,21 @@
2.33 {return CFConvertDoubleHostToSwapped(d);}
2.34 template <> inline double LittleEndian<double,CFSwappedFloat64>::makeNative (CFSwappedFloat64 d)
2.35 {return CFConvertDoubleSwappedToHost(d);}
2.36 -
2.37 +#else
2.38 + //FIXME: Not implemented yet for non-Mac platforms
2.39 + template <> inline uint32_t LittleEndian<uint32_t>::makeLittle (uint32_t i)
2.40 + {return i;}
2.41 + template <> inline uint32_t LittleEndian<uint32_t>::makeNative (uint32_t i)
2.42 + {return i;}
2.43 + template <> inline uint16_t LittleEndian<uint16_t>::makeLittle (uint16_t i)
2.44 + {return i;}
2.45 + template <> inline uint16_t LittleEndian<uint16_t>::makeNative (uint16_t i)
2.46 + {return i;}
2.47 + template <> inline CFSwappedFloat64 LittleEndian<double,CFSwappedFloat64>::makeLittle (double d)
2.48 + {return d;}
2.49 + template <> inline double LittleEndian<double,CFSwappedFloat64>::makeNative (CFSwappedFloat64 d)
2.50 + {return d;}
2.51 +#endif
2.52 }
2.53
2.54 #endif /* _MOOSEYARD_BASE_ */
3.1 --- a/include/File.h Mon Sep 28 23:39:08 2009 -0700
3.2 +++ b/include/File.h Tue Sep 29 15:46:42 2009 -0700
3.3 @@ -30,8 +30,7 @@
3.4 static const int kEOF = 10001;
3.5
3.6
3.7 - File (const char *filename, bool writeable =false, bool create =false) throw(Error);
3.8 - File (const char *filename, int oflag, bool locked) throw(Error);
3.9 + File (const char *filename, int oflag, bool locked =false) throw(Error);
3.10 ~File();
3.11
3.12 off_t length() const throw(Error);
3.13 @@ -90,10 +89,6 @@
3.14 private:
3.15 static int _open (const char *filename, int posixMode) throw(Error);
3.16 static int _check (int result) throw(Error);
3.17 -#ifdef OSX /* On linux, these are the same type signature to gcc */
3.18 - static ssize_t _check (ssize_t result) throw(Error) {_check((int)result); return result;}
3.19 - static off_t _check (off_t result) throw(Error) {_check((int)result); return result;}
3.20 -#endif
3.21 static void _checkRead (ssize_t result, size_t expectedSize) throw(Error);
3.22 bool _lock (bool block);
3.23 void _unlock();
4.1 --- a/src/File.cpp Mon Sep 28 23:39:08 2009 -0700
4.2 +++ b/src/File.cpp Tue Sep 29 15:46:42 2009 -0700
4.3 @@ -21,14 +21,8 @@
4.4
4.5 namespace Mooseyard {
4.6
4.7 - File::File (const char *filename, bool writeable, bool create) throw(Error)
4.8 - :_fd(_check( ::open(filename, writeable ?(create ?O_RDWR|O_CREAT :O_RDWR) :O_RDONLY, 0644) )),
4.9 - _memoryMap(NULL),
4.10 - _locked(0)
4.11 - { }
4.12 -
4.13 File::File (const char *filename, int oflag, bool locked) throw(Error)
4.14 -#if BSD
4.15 +#ifdef _DARWIN_C_SOURCE
4.16 :_fd(_check( ::open(filename, oflag | (locked ? O_EXLOCK : 0), 0644) )),
4.17 #else
4.18 :_fd(_check( ::open(filename, oflag, 0644) )),
4.19 @@ -36,7 +30,7 @@
4.20 _memoryMap(NULL),
4.21 _locked( locked ? 1 : 0)
4.22 {
4.23 -#if !BSDISH
4.24 +#ifndef _DARWIN_C_SOURCE
4.25 _check( ::flock(_fd, LOCK_EX) );
4.26 #endif
4.27 }
4.28 @@ -59,15 +53,21 @@
4.29 }
4.30
4.31 off_t File::position() const throw(Error) {
4.32 - return _check( lseek(_fd,0,SEEK_CUR) );
4.33 + off_t pos = lseek(_fd,0,SEEK_CUR);
4.34 + if (pos < 0)
4.35 + _check(-1);
4.36 + return pos;
4.37 }
4.38
4.39 void File::setPosition (off_t pos) throw(Error) {
4.40 - _check( lseek(_fd,pos,SEEK_SET) );
4.41 + _check( (int) lseek(_fd,pos,SEEK_SET) );
4.42 }
4.43
4.44 off_t File::setPositionToEnd (off_t bytesBefore) throw(Error) {
4.45 - return _check( lseek(_fd,-bytesBefore,SEEK_END) );
4.46 + off_t pos = lseek(_fd,-bytesBefore,SEEK_END);
4.47 + if (pos < 0)
4.48 + _check(-1);
4.49 + return pos;
4.50 }
4.51
4.52 void File::read (void *dst, size_t size) throw(Error) {
4.53 @@ -111,7 +111,13 @@
4.54 }
4.55
4.56 void File::flushDisk() throw(Error) {
4.57 -#if OSX
4.58 +#if _DARWIN_C_SOURCE
4.59 + /* F_FULLFSYNC is Mac/Darwin specific. From the man page:
4.60 + Does the same thing as fsync(2) then asks the drive to flush all buffered data to
4.61 + the permanent storage device (arg is ignored). This is currently implemented on
4.62 + HFS, MS-DOS (FAT), and Universal Disk Format (UDF) file systems. The operation may
4.63 + take quite a while to complete. Certain FireWire drives have also been known to
4.64 + ignore the request to flush their buffered data. */
4.65 _check( ::fcntl(_fd,F_FULLFSYNC) );
4.66 #else
4.67 _check( fsync(_fd) );
5.1 --- a/src/Index.cpp Mon Sep 28 23:39:08 2009 -0700
5.2 +++ b/src/Index.cpp Tue Sep 29 15:46:42 2009 -0700
5.3 @@ -15,10 +15,6 @@
5.4 #include <errno.h>
5.5 #include <algorithm>
5.6 #include <math.h>
5.7 -
5.8 -#define __STDC_LIMIT_MACROS /* I <3 you, C99 */
5.9 -# define UINT32_MAX (4294967295U)
5.10 -
5.11 #include <stdint.h>
5.12
5.13
6.1 --- a/src/Ottoman.cpp Mon Sep 28 23:39:08 2009 -0700
6.2 +++ b/src/Ottoman.cpp Tue Sep 29 15:46:42 2009 -0700
6.3 @@ -42,6 +42,7 @@
6.4
6.5 Ottoman::Ottoman()
6.6 :_writeable(true),
6.7 + _file(NULL),
6.8 _filename(NULL),
6.9 _lastVersion(NULL),
6.10 _current( new OverlayDictionary(&Dictionary::kEmpty) )
6.11 @@ -96,6 +97,9 @@
6.12 delete _file;
6.13 _file = curFile;
6.14 }
6.15 +
6.16 + if (changed)
6.17 + versionsChanged();
6.18 return changed;
6.19 }
6.20
6.21 @@ -196,11 +200,12 @@
6.22 if (!lastVersion)
6.23 lastVersion = new VersionDictionary(dstFile);
6.24 VersionDictionary *saved = lastVersion->_appendAndOpen(_current->overlay(),
6.25 - dstFile,
6.26 - _current->baseReplaced());
6.27 + dstFile,
6.28 + _current->baseReplaced());
6.29 // (don't delete _lastVersion: saved->_previousVersion now points to it.)
6.30 _lastVersion = saved;
6.31 _current->revertTo(_lastVersion);
6.32 + versionsChanged();
6.33 }
6.34
6.35 bool Ottoman::save() {
6.36 @@ -235,6 +240,7 @@
6.37 File *dstFile = _writeTo(dstFileName, overwriteAllowed);
6.38 free(_filename);
6.39 _filename = strdup(dstFileName);
6.40 + delete _file;
6.41 _file = dstFile;
6.42 }
6.43
6.44 @@ -242,8 +248,13 @@
6.45 if (!_file)
6.46 return false;
6.47 char tempFileName[1024];
6.48 +#ifdef _DARWIN_C_SOURCE
6.49 + ::strlcpy(tempFileName, _filename, sizeof(tempFileName)-1);
6.50 + ::strlcat(tempFileName, "~", sizeof(tempFileName));
6.51 +#else
6.52 ::strncpy(tempFileName, _filename, sizeof(tempFileName)-1);
6.53 ::strncat(tempFileName, "~", sizeof(tempFileName));
6.54 +#endif
6.55 File *tempFile;
6.56 {
6.57 // Check for conflict in existing file:
7.1 --- a/src/VersionDictionary.cpp Mon Sep 28 23:39:08 2009 -0700
7.2 +++ b/src/VersionDictionary.cpp Tue Sep 29 15:46:42 2009 -0700
7.3 @@ -12,13 +12,12 @@
7.4 #include "Index.h"
7.5 #include "File.h"
7.6 #include "Chunk.h"
7.7 +#include <algorithm>
7.8 #include <assert.h>
7.9 #include <errno.h>
7.10 -#include <algorithm>
7.11 +#include <stdint.h>
7.12 #include <time.h>
7.13
7.14 -# define UINT32_MAX (4294967295U)
7.15 -
7.16
7.17 namespace Mooseyard {
7.18
7.19 @@ -153,9 +152,8 @@
7.20
7.21 // Verify Indexes:
7.22 for (int i=0; i<256; i++) {
7.23 - if (_indexPositions[i] > 0)
7.24 - if (_indexPositions[i] < _previousTrailerPosition || _indexPositions[i] >= _trailerPosition)
7.25 - throw File::Error("Bad VersionDictionary trailer (illegal index position)");
7.26 + if (_indexPositions[i] >= _trailerPosition)
7.27 + throw File::Error("Bad VersionDictionary trailer (illegal index position)");
7.28 const Index *index = _index(i);
7.29 if (index)
7.30 index->validate();
7.31 @@ -289,10 +287,13 @@
7.32 dstFile->flushDisk();
7.33
7.34 // Write the trailer:
7.35 + FilePosition previousTrailerPosition = 0;
7.36 + if (dstFile==srcFile)
7.37 + previousTrailerPosition = baseDict->_trailerPosition;
7.38 FilePosition newTrailerPosition = pos;
7.39 VersionDictionary::Trailer trailer(newCount,
7.40 newIndexPositions,
7.41 - baseDict->_trailerPosition,
7.42 + previousTrailerPosition,
7.43 baseDict->generation() + 1);
7.44 pos += dstFile->write(trailer);
7.45
7.46 @@ -312,10 +313,7 @@
7.47 }
7.48 }
7.49
7.50 -
7.51 -#pragma mark -
7.52 -#pragma mark TESTING-ONLY:
7.53 -
7.54 +
7.55 VersionDictionary* VersionDictionary::_appendAndOpen (const Dictionary *addDict,
7.56 File *dstFile,
7.57 bool replace) const
7.58 @@ -326,6 +324,10 @@
7.59 return nextVersion;
7.60 }
7.61
7.62 +
7.63 +#pragma mark -
7.64 +#pragma mark TESTING-ONLY:
7.65 +
7.66 VersionDictionary* VersionDictionary::create (File *file, const Dictionary *srcDict) {
7.67 return VersionDictionary(file)._appendAndOpen(srcDict, file, true);
7.68 }
8.1 --- a/test/TestUtils.cpp Mon Sep 28 23:39:08 2009 -0700
8.2 +++ b/test/TestUtils.cpp Tue Sep 29 15:46:42 2009 -0700
8.3 @@ -25,7 +25,7 @@
8.4
8.5 void shuffle(int a[], int n, unsigned seed) {
8.6 if (seed==0) {
8.7 -#ifdef BSD
8.8 +#ifdef _DARWIN_C_SOURCE
8.9 srandomdev();
8.10 #endif
8.11 seed = random();
8.12 @@ -54,16 +54,11 @@
8.13 while (NULL != ::fgets(word, 4096, in)) {
8.14 wordLen = ::strlen(word);
8.15 if (word[wordLen-1]=='\n') {
8.16 - word[wordLen-1] = '\0';
8.17 - wordLen--;
8.18 - }
8.19 -
8.20 - if (wordLen == 0) continue;
8.21 -
8.22 - sWords[sNWords] = strdup(word);
8.23 - //if( sNWords % 10000 == 0)
8.24 - // printf("'%s' ... ", sWords[sNWords]->string());
8.25 - sNWords++;
8.26 + word[wordLen-1] = '\0';
8.27 + wordLen--;
8.28 + }
8.29 + if (wordLen > 0)
8.30 + sWords[sNWords++] = strdup(word);
8.31 }
8.32 }
8.33 }
8.34 @@ -99,7 +94,7 @@
8.35 using namespace Mooseyard;
8.36
8.37 int main(int argc, char **argv) {
8.38 -#if BSD
8.39 +#ifdef _DARWIN_C_SOURCE
8.40 srandomdev();
8.41 #endif
8.42 try {
9.1 --- a/test/VersionDictionary_test.cpp Mon Sep 28 23:39:08 2009 -0700
9.2 +++ b/test/VersionDictionary_test.cpp Tue Sep 29 15:46:42 2009 -0700
9.3 @@ -46,16 +46,16 @@
9.4
9.5 TEST(File,HasPath) {
9.6 {
9.7 - File f("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC, true);
9.8 + File f("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC);
9.9 f.write("howdy");
9.10 }
9.11 {
9.12 - File f("/tmp/jubba", O_RDWR, true);
9.13 + File f("/tmp/jubba", O_RDWR);
9.14 EXPECT_TRUE(f.hasPath("/tmp/jubba"));
9.15 File::unlink("/tmp/jubba");
9.16 EXPECT_FALSE(f.hasPath("/tmp/jubba"));
9.17
9.18 - File f2("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC, true);
9.19 + File f2("/tmp/jubba", O_RDWR | O_CREAT | O_TRUNC);
9.20 f2.write("howdy");
9.21 f2.flush();
9.22
9.23 @@ -108,7 +108,7 @@
9.24 time_t startTime = ::time(NULL);
9.25 time_t createTime;
9.26 {
9.27 - File file("/tmp/hashfiletest", O_RDWR | O_CREAT | O_TRUNC, true);
9.28 + File file("/tmp/hashfiletest", O_RDWR | O_CREAT | O_TRUNC);
9.29 VersionDictionary *hf;
9.30 {
9.31 Timer t("Creating & writing VersionDictionary", nWords);
9.32 @@ -124,7 +124,7 @@
9.33 delete hf;
9.34 }
9.35 {
9.36 - File file("/tmp/hashfiletest");
9.37 + File file("/tmp/hashfiletest", O_RDONLY);
9.38 VersionDictionary hf(&file);
9.39 ASSERT_EQ(0, hf.generation());
9.40 ASSERT_EQ(createTime, hf.timestamp());
9.41 @@ -152,7 +152,7 @@
9.42 }
9.43 {
9.44 printf("Opening OverlayVersionDictionary...\n");
9.45 - File file("/tmp/hashfiletest", O_RDWR, true);
9.46 + File file("/tmp/hashfiletest", O_RDWR);
9.47 OverlayVersionDictionary hf(&file);
9.48 EXPECT_EQ( nWords , hf.count() );
9.49 EXPECT_TRUE(hf.get("abatement").equals("abatement"));
9.50 @@ -196,7 +196,7 @@
9.51 }
9.52 {
9.53 printf("Re-opening OverlayVersionDictionary...\n");
9.54 - File file("/tmp/hashfiletest");
9.55 + File file("/tmp/hashfiletest", O_RDONLY);
9.56 OverlayVersionDictionary hf(&file);
9.57
9.58 ASSERT_EQ(1, hf.generation());
9.59 @@ -222,17 +222,17 @@
9.60 }
9.61 {
9.62 printf("Writing VersionDictionary to a new file...\n");
9.63 - File oldFile("/tmp/hashfiletest");
9.64 + File oldFile("/tmp/hashfiletest", O_RDONLY);
9.65 OverlayVersionDictionary oldhf(&oldFile);
9.66
9.67 - File newFile("/tmp/hashfiletest2", O_RDWR | O_CREAT | O_TRUNC, true);
9.68 + File newFile("/tmp/hashfiletest2", O_RDWR | O_CREAT | O_TRUNC);
9.69 newFile.write("Ha5h", 4); // VersionDictionary won't write to an empty file
9.70 oldhf.saveAs(&newFile);
9.71 printf("File size: %llu bytes\n", newFile.length());
9.72 }
9.73 {
9.74 printf("Opening new file...\n");
9.75 - File file("/tmp/hashfiletest2");
9.76 + File file("/tmp/hashfiletest2", O_RDONLY);
9.77 OverlayVersionDictionary hf(&file);
9.78
9.79 EXPECT_EQ( nWords , hf.count() );