00001 00004 /* Copyright (C) 2004,2005,2006,2007,2008,2009,2010 Olly Betts 00005 * 00006 * This program is free software; you can redistribute it and/or 00007 * modify it under the terms of the GNU General Public License as 00008 * published by the Free Software Foundation; either version 2 of the 00009 * License, or (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 00019 * USA 00020 */ 00021 00022 #ifndef XAPIAN_INCLUDED_BYTE_LENGTH_STRINGS_H 00023 #define XAPIAN_INCLUDED_BYTE_LENGTH_STRINGS_H 00024 00025 #include <xapian/error.h> 00026 00027 #include <string> 00028 00029 // We XOR the length values with this so that they are more likely to coincide 00030 // with lower case ASCII letters, which are likely to be common. This means 00031 // that zlib should do a better job of compressing tag values - in tests, this 00032 // gave 5% better compression. 00033 #define MAGIC_XOR_VALUE 96 00034 00035 class ByteLengthPrefixedStringItor { 00036 const unsigned char * p; 00037 size_t left; 00038 00039 ByteLengthPrefixedStringItor(const unsigned char * p_, size_t left_) 00040 : p(p_), left(left_) { } 00041 00042 public: 00043 ByteLengthPrefixedStringItor(const std::string & s) 00044 : p(reinterpret_cast<const unsigned char *>(s.data())), 00045 left(s.size()) { } 00046 00047 std::string operator*() const { 00048 size_t len = *p ^ MAGIC_XOR_VALUE; 00049 return std::string(reinterpret_cast<const char *>(p + 1), len); 00050 } 00051 00052 ByteLengthPrefixedStringItor operator++(int) { 00053 const unsigned char * old_p = p; 00054 size_t old_left = left; 00055 operator++(); 00056 return ByteLengthPrefixedStringItor(old_p, old_left); 00057 } 00058 00059 ByteLengthPrefixedStringItor & operator++() { 00060 if (!left) { 00061 throw Xapian::DatabaseCorruptError("Bad synonym data (none left)"); 00062 } 00063 size_t add = (*p ^ MAGIC_XOR_VALUE) + 1; 00064 if (left < add) { 00065 throw Xapian::DatabaseCorruptError("Bad synonym data (too little left)"); 00066 } 00067 p += add; 00068 left -= add; 00069 return *this; 00070 } 00071 00072 bool at_end() const { 00073 return left == 0; 00074 } 00075 }; 00076 00077 struct ByteLengthPrefixedStringItorGt { 00079 bool operator()(const ByteLengthPrefixedStringItor *a, 00080 const ByteLengthPrefixedStringItor *b) { 00081 return (**a > **b); 00082 } 00083 }; 00084 00085 #endif // XAPIAN_INCLUDED_BYTE_LENGTH_STRINGS_H