00001 /* quartz_metafile.cc: Management of quartz meta-file 00002 * 00003 * Copyright 1999,2000,2001 BrightStation PLC 00004 * Copyright 2002 Ananova Ltd 00005 * Copyright 2002,2003,2004,2007 Olly Betts 00006 * 00007 * This program is free software; you can redistribute it and/or 00008 * modify it under the terms of the GNU General Public License as 00009 * published by the Free Software Foundation; either version 2 of the 00010 * License, or (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 00020 * USA 00021 */ 00022 00023 #include <config.h> 00024 00025 #include <xapian/error.h> 00026 00027 #include <string> 00028 00029 #include "quartz_metafile.h" 00030 #include "btree_util.h" 00031 #include "omassert.h" 00032 #include "omdebug.h" 00033 #include "stringutils.h" 00034 #include "utils.h" 00035 00036 using std::string; 00037 00038 static const string metafile_magic = "OMMETA"; 00039 static const unsigned int metafile_version = 1; 00040 00041 static const size_t min_metafile_size = metafile_magic.length() + 4; 00042 00043 static const size_t max_metafile_size = min_metafile_size; 00044 00045 static string encode_version(unsigned int version) 00046 { 00047 string data; 00048 00049 for (size_t i = 0; i < 4; ++i) { 00050 data += char(version); 00051 version >>= 8; 00052 } 00053 00054 return data; 00055 } 00056 00057 static unsigned int decode_version(const string &s) 00058 { 00059 unsigned int version = 0; 00060 00061 for (size_t i = 1; i <= 4; ++i) { 00062 version = (version << 8) + s[4 - i]; 00063 } 00064 00065 return version; 00066 } 00067 00068 void QuartzMetaFile::open() 00069 { 00070 int fd = sys_open_to_read(filename); 00071 string data = sys_read_all_bytes(fd, min_metafile_size + 1); 00072 sys_close(fd); 00073 00074 if (data.length() < min_metafile_size) { 00075 throw Xapian::DatabaseCorruptError("Quartz metafile " + filename + 00076 " too short; may be truncated."); 00077 } 00078 00079 if (!startswith(data, metafile_magic)) { 00080 throw Xapian::DatabaseCorruptError("Quartz metafile " + filename + 00081 " is invalid: magic string not found."); 00082 } 00083 00084 unsigned int version; 00085 version = decode_version(data.substr(metafile_magic.length(), 4)); 00086 if (version != metafile_version) { 00087 throw Xapian::DatabaseVersionError("Unknown Quartz metafile version " + 00088 om_tostring(version) + " in " + 00089 filename); 00090 } 00091 00092 if (data.length() > max_metafile_size) { 00093 throw Xapian::DatabaseCorruptError("Quartz metafile " + filename + 00094 " contains extra garbage."); 00095 } 00096 } 00097 00098 void QuartzMetaFile::create() 00099 { 00100 string data = metafile_magic; 00101 data += encode_version(metafile_version); 00102 00103 int fd = sys_open_to_write(filename); 00104 sys_write_string(fd, data); 00105 sys_close(fd); 00106 }