[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kmail-devel
Subject:    Re: kmail under Solaris and Linux
From:       Waldo Bastian <bastian () kde ! org>
Date:       2002-02-02 2:49:03
[Download RAW message or body]

On Thursday 31 January 2002 11:02 pm, Michael Häckel wrote:
> On Thursday 31 January 2002 23:00:23, Waldo Bastian wrote:
> > Can't we add a byte-order indicator at the start of the index file? Then,
> > when the byte order doesn't match we can use a slower compatibility
> > function that fixes the byte order. In 99.9% of the cases this will not
> > be needed but when it is needed it wil be used automagically and hassle
> > free.
> >
> > I can make a patch for it if you like the idea.
>
> This is not only required for the index file but also for the sorted and
> serial number files.

Ok... first attempt. Make sure to backup your Mail folder first!

It adds a two word (8 byte) header to the index file which contains a byte 
order indicator and the size of long (4 or 8) used for the index file.

If the header is not present we assume that both the byte order and the size 
of long of the index file matches with that of the host.

The QStrings are always written in network order, just as with Qt 2. That 
means that if the host order differs from network order, they are swapped 
first, before being written. If the host order _is_ network order, they are 
NOT swapped! 

This means that the patch is supposed to restore compatibility on Sparc with 
KDE 2 index-files, but it will probably also mean that it breaks 
compatibility on Sparc with KDE 3 beta1/2 index-files. During testing I 
noticed that you will get lots of chinese (korean?) in the subjects of your 
msg-list in that case. (Do not panic! :-) Selecting the message should result 
in the proper subject being shown.

I have replaced all ints with either Q_UINT32 or Q_INT32, int seems to be 
always 4 bytes, even on 64-bit platforms but we better use an explicit 32-bit 
type to minimize surprises.

I also converted MsgPartType to Q_UINT32. gcc gives sizeof(MsgpartType) == 4 , 
but I'm not sure if every compiler does.

The long is another story. It will be either 64 bit or 32 bit. If the size of 
long in the index file doesn't match with the size of long of the host, the 
long is converted. The conversion from 64 bit to 32 bit just drops the 32 
most significant bits. 32 bit seems to be enough for most info.... it will be 
enough for the date till 2038 and it will be enough for the offset as long as 
the mbox file does not exceed 4Gb. (But if your mbox is 4Gb, you probably 
shouldn't be using mbox.)

I added a byteOrder field to the sorted index, if the byte order doesn't match 
with the host order it throws away the file. (I should recheck if there are 
types used there that can have a variable size across platforms, I don't 
think so)

I added a byteOrder field to the msg id index. If the byteorder doesn't match 
it swaps the message ids. I also changed the message ids from "unsigned long" 
to Q_UINT32. That makes that 64-bit platforms will now use a 32-bit message 
id as well. I don't think 64 bits are needed here since I don't think anyone 
is going to receive so many messages that he needs more than 32 bits for 
that.

Patch attached.

It works fine for me, but I haven't tested it cross-platform yet. If you test 
it make sure to backup your Mail directory first.

Cheers,
Waldo
-- 
bastian@kde.org  |   SuSE Labs KDE Developer  |  bastian@suse.com

["kmail.portable.patch" (text/x-diff)]

Index: kmfolder.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolder.cpp,v
retrieving revision 1.215
diff -u -r1.215 kmfolder.cpp
--- kmfolder.cpp	2002/01/20 22:20:08	1.215
+++ kmfolder.cpp	2002/02/02 02:05:24
@@ -22,6 +22,7 @@
 #include <errno.h>
 #include <assert.h>
 #include <unistd.h>
+#include <endian.h>
 
 #ifdef HAVE_CONFIG_H
 #include <config.h>
@@ -31,6 +32,22 @@
 #include <fcntl.h>
 #endif
 
+#if HAVE_BYTESWAP_H
+#include <byteswap.h>
+#endif
+
+// We define functions as kmail_swap_NN so that we don't get compile errors
+// on platforms where bswap_NN happens to be a function instead of a define.
+
+/* Swap bytes in 32 bit value.  */
+#ifdef bswap_32
+#define kmail_swap_32(x) bswap_32(x)
+#else
+#define kmail_swap_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |		      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+#endif
+
 //#define HAVE_MMAP //need to get this into autoconf FIXME  --Sam
 #ifdef HAVE_MMAP
 #include <unistd.h>
@@ -83,6 +100,8 @@
   mIndexId        = -1;
   mIndexStreamPtr = NULL;
   mIndexStreamPtrLength = 0;
+  mIndexSwapByteOrder = false;
+  mIndexSizeOfLong = sizeof(long);
   mCompactable     = TRUE;
   mNoContent      = FALSE;
   expireMessages = FALSE;
@@ -220,11 +239,20 @@
     return errno;
 
   fprintf(tmpIndexStream, "# KMail-Index V%d\n", INDEX_VERSION);
+
+  // Header
+  Q_UINT32 byteOrder = 0x12345678;
+  Q_UINT32 sizeOfLong = sizeof(long);
+
+  Q_UINT32 header_length = sizeof(byteOrder)+sizeof(sizeOfLong); 
   char pad_char = '\0';
-  int header_length = 0; // Reserved for future expansion
   fwrite(&pad_char, sizeof(pad_char), 1, tmpIndexStream);
   fwrite(&header_length, sizeof(header_length), 1, tmpIndexStream);
 
+  // Write header 
+  fwrite(&byteOrder, sizeof(byteOrder), 1, tmpIndexStream);
+  fwrite(&sizeOfLong, sizeof(sizeOfLong), 1, tmpIndexStream);
+
   long nho = ftell(tmpIndexStream);
   for (i=0; i<mMsgList.high(); i++)
   {
@@ -269,6 +297,8 @@
 {
   int indexVersion;
   assert(mIndexStream != NULL);
+  mIndexSwapByteOrder = false;
+  mIndexSizeOfLong = sizeof(long);
 
   fscanf(mIndexStream, "# KMail-Index V%d\n", &indexVersion);
   if(gv)
@@ -280,7 +310,6 @@
       }
       return TRUE;
   } else if (indexVersion == 1505) {
-      fseek(mIndexStream, sizeof(char), SEEK_CUR );
   } else if (indexVersion < INDEX_VERSION) {
       kdDebug(5006) << "Index file " << indexLocation() << " is out of date. \
Re-creating it." << endl;  createIndexFromContents();
@@ -299,10 +328,42 @@
       return FALSE;
   }
   else {
-      int header_length = 0;
+      // Header
+      Q_UINT32 byteOrder = 0;
+      Q_UINT32 sizeOfLong = sizeof(long); // default
+
+      Q_UINT32 header_length = 0;
       fseek(mIndexStream, sizeof(char), SEEK_CUR );
       fread(&header_length, sizeof(header_length), 1, mIndexStream);
-      fseek(mIndexStream, header_length, SEEK_CUR );
+      if (header_length > 0xFFFF)
+         header_length = kmail_swap_32(header_length);
+      
+      long endOfHeader = ftell(mIndexStream) + header_length;
+qWarning("header_lenght = %d", header_length);
+
+      // Process available header parts
+      if (header_length >= sizeof(byteOrder))
+      {
+         fread(&byteOrder, sizeof(byteOrder), 1, mIndexStream);
+         mIndexSwapByteOrder = (byteOrder == 0x78563412);
+         header_length -= sizeof(byteOrder);
+      
+         if (header_length >= sizeof(sizeOfLong))
+         {
+            fread(&sizeOfLong, sizeof(sizeOfLong), 1, mIndexStream);
+            mIndexSizeOfLong = sizeOfLong;
+            header_length -= sizeof(sizeOfLong);
+         }
+      }
+
+      // Seek to end of header
+      fseek(mIndexStream, endOfHeader, SEEK_SET );
+
+      if (mIndexSwapByteOrder)
+         kdDebug(5006) << "Index File has byte order swapped!" << endl;
+      if (mIndexSizeOfLong != sizeof(long))
+         kdDebug(5006) << "Index File sizeOfLong is " << mIndexSizeOfLong << " while \
sizeof(long) is " << sizeof(long) << " !" << endl; +
   }
   return TRUE;
 }
@@ -311,7 +372,8 @@
 //-----------------------------------------------------------------------------
 bool KMFolder::readIndex()
 {
-  int len, offs;
+  Q_INT32 len;
+  int offs;
   KMMsgInfo* mi;
 
   assert(mIndexStream != NULL);
@@ -331,10 +393,13 @@
     mi = NULL;
     if(version >= 1505) {
       if(!fread(&len, sizeof(len), 1, mIndexStream))
-	break;
+        break;
+      if (mIndexSwapByteOrder)
+        len = kmail_swap_32(len);
+
       offs = ftell(mIndexStream);
       if(fseek(mIndexStream, len, SEEK_CUR))
-	break;
+        break;
       mi = new KMMsgInfo(this, offs, len);
     } else {
       QCString line(MAX_LINE);
Index: kmfolder.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolder.h,v
retrieving revision 1.79
diff -u -r1.79 kmfolder.h
--- kmfolder.h	2002/01/05 19:57:21	1.79
+++ kmfolder.h	2002/02/02 02:05:26
@@ -306,7 +306,10 @@
   /** Returns a string that can be used to identify this folder */
   virtual QString idString();
 
-    uchar *indexStreamBasePtr() { return mIndexStreamPtr; }
+  uchar *indexStreamBasePtr() { return mIndexStreamPtr; }
+  
+  bool indexSwapByteOrder() { return mIndexSwapByteOrder; }
+  int  indexSizeOfLong() { return mIndexSizeOfLong; }
 
   /**
    * Set whether this folder automatically expires messages.
@@ -539,6 +542,8 @@
   bool mConvertToUtf8;
   uchar *mIndexStreamPtr;
   int mIndexStreamPtrLength, mIndexId;
+  bool mIndexSwapByteOrder; // Index file was written with swapped byte order
+  int mIndexSizeOfLong; // Index file was written with longs of this size
 
   /** Support for automatic expiry of old messages */
   bool         expireMessages;          // TRUE if old messages are expired
@@ -551,7 +556,6 @@
   
   /** Points at the reverse dictionary for this folder. */
   KMMsgDictREntry *mRDict;
-
 };
 
 #endif /*kmfolder_h*/
Index: kmheaders.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmheaders.cpp,v
retrieving revision 1.389
diff -u -r1.389 kmheaders.cpp
--- kmheaders.cpp	2002/01/27 10:24:28	1.389
+++ kmheaders.cpp	2002/02/02 02:05:33
@@ -2726,7 +2726,7 @@
 }
 
 //Flatten the list and write it to disk
-#define KMAIL_SORT_VERSION 1006
+#define KMAIL_SORT_VERSION 1007
 #define KMAIL_SORT_FILE(x) x->indexLocation() + ".sorted"
 #define KMAIL_SORT_HEADER "## KMail Sort V%04d\n\t"
 #define KMAIL_MAGIC_HEADER_OFFSET 21 //strlen(KMAIL_SORT_HEADER)
@@ -2736,14 +2736,14 @@
 {
   fwrite(&msgid, sizeof(msgid), 1, sortStream);
   fwrite(&parent_id, sizeof(parent_id), 1, sortStream);
-  int len = key.length() * 2;
+  Q_INT32 len = key.length() * sizeof(QChar);
   fwrite(&len, sizeof(len), 1, sortStream);
   if (len)
     fwrite(key.unicode(), QMIN(len, KMAIL_MAX_KEY_LEN), 1, sortStream);
 
   if (update_discover) {
     //update the discovered change count
-      int discovered_count = 0;
+      Q_INT32 discovered_count = 0;
       fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET);
       fread(&discovered_count, sizeof(discovered_count), 1, sortStream);
       discovered_count++;
@@ -2773,9 +2773,14 @@
     mSortInfo.dirty = FALSE;
     fprintf(sortStream, KMAIL_SORT_HEADER, KMAIL_SORT_VERSION);
     //magic header information
-    int column = mSortCol, ascending=!mSortDescending;
-    int threaded = (mNested != mNestedOverride);
-    int discovered_count = 0, sorted_count=0, appended=0;
+    Q_INT32 byteOrder = 0x12345678;
+    Q_INT32 column = mSortCol;
+    Q_INT32 ascending= !mSortDescending;
+    Q_INT32 threaded = (mNested != mNestedOverride);
+    Q_INT32 appended=0;
+    Q_INT32 discovered_count = 0;
+    Q_INT32 sorted_count=0;
+    fwrite(&byteOrder, sizeof(byteOrder), 1, sortStream);
     fwrite(&column, sizeof(column), 1, sortStream);
     fwrite(&ascending, sizeof(ascending), 1, sortStream);
     fwrite(&threaded, sizeof(threaded), 1, sortStream);
@@ -2832,6 +2837,7 @@
 
     //magic header twice, case they've changed
     fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET, SEEK_SET);
+    fwrite(&byteOrder, sizeof(byteOrder), 1, sortStream);
     fwrite(&column, sizeof(column), 1, sortStream);
     fwrite(&ascending, sizeof(ascending), 1, sortStream);
     fwrite(&threaded, sizeof(threaded), 1, sortStream);
@@ -2867,8 +2873,8 @@
 		      khi->key(mSortCol, !mSortDescending));
 
     //update the appended flag
-    int appended = 1;
-    fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 12, SEEK_SET);
+    Q_INT32 appended = 1;
+    fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET);
     fwrite(&appended, sizeof(appended), 1, sortStream);
 
     if (sortStream && ferror(sortStream)) {
@@ -2980,7 +2986,7 @@
 bool KMHeaders::readSortOrder(bool set_selection)
 {
     //all cases
-    int column, ascending, threaded, discovered_count, sorted_count, appended;
+    Q_INT32 column, ascending, threaded, discovered_count, sorted_count, appended;
     bool unread_exists = false;
     QMemArray<KMSortCacheItem *> sortCache(mFolder->count());
     KMSortCacheItem root;
@@ -3012,6 +3018,10 @@
 	int version;
 	fscanf(sortStream, KMAIL_SORT_HEADER, &version);
 	if(version == KMAIL_SORT_VERSION) {
+	  Q_INT32 byteOrder = 0;
+	  fread(&byteOrder, sizeof(byteOrder), 1, sortStream);
+	  if (byteOrder == 0x12345678)
+	  {
 	    fread(&column, sizeof(column), 1, sortStream);
 	    fread(&ascending, sizeof(ascending), 1, sortStream);
 	    fread(&threaded, sizeof(threaded), 1, sortStream);
@@ -3121,6 +3131,11 @@
 		fclose(sortStream);
 		sortStream = NULL;
 	    }
+	  }
+	  else {
+	      fclose(sortStream);
+ 	      sortStream = NULL;
+	  }
 	} else {
 	    fclose(sortStream);
 	    sortStream = NULL;
@@ -3245,7 +3260,7 @@
 	} else {
 	    //update the appended flag
 	    appended = 0;
-	    fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 12, SEEK_SET);
+	    fseek(sortStream, KMAIL_MAGIC_HEADER_OFFSET + 16, SEEK_SET);
 	    fwrite(&appended, sizeof(appended), 1, sortStream);
 	}
     }
Index: kmmsgbase.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmsgbase.cpp,v
retrieving revision 1.104
diff -u -r1.104 kmmsgbase.cpp
--- kmmsgbase.cpp	2002/01/16 12:43:35	1.104
+++ kmmsgbase.cpp	2002/02/02 02:05:35
@@ -16,7 +16,47 @@
 #include <ctype.h>
 #include <stdlib.h>
 
+#include <config.h>
 
+#if HAVE_BYTESWAP_H
+#include <byteswap.h>
+#endif
+
+// We define functions as kmail_swap_NN so that we don't get compile errors
+// on platforms where bswap_NN happens to be a function instead of a define.
+
+/* Swap bytes in 16 bit value.  */
+#ifdef bswap_16
+#define kmail_swap_16(x) bswap_16(x)
+#else 
+#define kmail_swap_16(x) \
+     ((((x) >> 8) & 0xff) | (((x) & 0xff) << 8))
+#endif
+
+/* Swap bytes in 32 bit value.  */
+#ifdef bswap_32
+#define kmail_swap_32(x) bswap_32(x)
+#else
+#define kmail_swap_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |		      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+#endif
+
+/* Swap bytes in 64 bit value.  */
+#ifdef bswap_64
+#define kmail_swap_64(x) bswap_64(x)
+#else
+#define kmail_swap_64(x) \
+     ((((x) & 0xff00000000000000ull) >> 56)				      \
+      | (((x) & 0x00ff000000000000ull) >> 40)				      \
+      | (((x) & 0x0000ff0000000000ull) >> 24)				      \
+      | (((x) & 0x000000ff00000000ull) >> 8)				      \
+      | (((x) & 0x00000000ff000000ull) << 8)				      \
+      | (((x) & 0x0000000000ff0000ull) << 24)				      \
+      | (((x) & 0x000000000000ff00ull) << 40)				      \
+      | (((x) & 0x00000000000000ffull) << 56))
+#endif
+
 static KMMsgStatus sStatusList[] =
 {
   KMMsgStatusDeleted, KMMsgStatusNew,
@@ -681,7 +721,7 @@
   for (uint i = 0; i < len; i++)
   {
     us = str[i].unicode();
-    str[i] = QChar(((us & 0xFF) << 8) + ((us & 0xFF00) >> 8));
+    str[i] = QChar(kmail_swap_16(us));
   }
 }
 
@@ -698,8 +738,8 @@
         memcpy(x, g_chunk+g_chunk_offset, length); \
 	g_chunk_offset += length; \
      } } while(0)
-#define COPY_HEADER_TYPE(x) Q_ASSERT(sizeof(x) == sizeof(MsgPartType)); \
                COPY_DATA(&x, sizeof(x))
-#define COPY_HEADER_LEN(x)  Q_ASSERT(sizeof(x) == sizeof(short)); COPY_DATA(&x, \
sizeof(x)); +#define COPY_HEADER_TYPE(x) Q_ASSERT(sizeof(x) == sizeof(Q_UINT32)); \
COPY_DATA(&x, sizeof(x)); +#define COPY_HEADER_LEN(x)  Q_ASSERT(sizeof(x) == \
sizeof(Q_UINT16)); COPY_DATA(&x, sizeof(x));  \
//-----------------------------------------------------------------------------  \
QString KMMsgBase::getStringPart(MsgPartType t) const  {
@@ -707,6 +747,7 @@
 
   g_chunk_offset = 0;
   bool using_mmap = FALSE;
+  bool swapByteOrder = mParent->indexSwapByteOrder();
   if (mParent->indexStreamBasePtr()) {
     if (g_chunk)
 	free(g_chunk);
@@ -725,15 +766,21 @@
   }
 
   MsgPartType type;
-  short l;
+  Q_UINT16 l;
   while(g_chunk_offset < mIndexLength) {
-    COPY_HEADER_TYPE(type);
+    Q_UINT32 tmp;
+    COPY_HEADER_TYPE(tmp);
+    type = (MsgPartType) tmp;
     COPY_HEADER_LEN(l);
+    if (swapByteOrder)
+       l = kmail_swap_16(l);
     if(g_chunk_offset + l > mIndexLength) {
 	kdDebug(5006) << "This should never happen.. " << __FILE__ << ":" << __LINE__ << \
endl;  break;
     }
     if(type == t) {
+        // This works because the QString constructor does a memcpy.
+        // Otherwise we would need to be concerned about the alignment.
 	if(l)
 	    ret = QString((QChar *)(g_chunk + g_chunk_offset), l/2);
 	break;
@@ -744,7 +791,25 @@
       g_chunk_length = 0;
       g_chunk = NULL;
   }
-  swapEndian(ret);
+  // Normally we need to swap the byte order because the QStrings are written
+  // in the style of Qt2 (MSB -> network ordered). 
+  // QStrings in Qt3 expect host ordering.
+  // On e.g. Intel host ordering is LSB, on e.g. Sparc it is MSB.
+#ifndef BYTE_ORDER
+  assert(false); // Uh oh.
+#endif
+
+#if BYTE_ORDER == LITTLE_ENDIAN
+#warning Byte order is little endian (swap is true)
+  bool swap_endian = true;
+#else
+#warning Byte order is big endian (swap is false)
+  bool swap_endian = false;
+#endif  
+  swap_endian = swap_endian ^ swapByteOrder; // index-file has non-native byte \
order. +
+  if (swap_endian)
+     swapEndian(ret);
   return ret;
 }
 
@@ -755,6 +820,8 @@
 
   g_chunk_offset = 0;
   bool using_mmap = FALSE;
+  int sizeOfLong = mParent->indexSizeOfLong();
+  bool swapByteOrder = mParent->indexSwapByteOrder();
   if (mParent->indexStreamBasePtr()) {
     if (g_chunk)
       free(g_chunk);
@@ -774,18 +841,74 @@
   }
 
   MsgPartType type;
-  short l;
+  Q_UINT16 l;
   while (g_chunk_offset < mIndexLength) {
-    COPY_HEADER_TYPE(type);
+    Q_UINT32 tmp;
+    COPY_HEADER_TYPE(tmp);
+    type = (MsgPartType) tmp;
     COPY_HEADER_LEN(l);
+    if (swapByteOrder)
+       l = kmail_swap_16(l);
 
     if (g_chunk_offset + l > mIndexLength) {
       kdDebug(5006) << "This should never happen.. " << __FILE__ << ":" << __LINE__ \
<< endl;  break;
     }
     if(type == t) {
-      Q_ASSERT(l == sizeof(unsigned long));
-      COPY_DATA(&ret, sizeof(ret));
+      assert(sizeOfLong == l);
+      if (sizeOfLong == sizeof(ret))
+      {
+         COPY_DATA(&ret, sizeof(ret));
+         if (swapByteOrder)
+         {
+            if (sizeof(ret) == 4)
+               ret = kmail_swap_32(ret);
+            else
+               ret = kmail_swap_64(ret);
+         }
+      }
+      else if (sizeOfLong == 4)
+      {
+         // Long is stored as 4 bytes in index file, sizeof(long) = 8
+         Q_UINT32 ret_32;
+         COPY_DATA(&ret_32, sizeof(ret_32));
+         if (swapByteOrder)
+            ret_32 = kmail_swap_32(ret_32);
+         ret = ret_32;
+      }
+      else if (sizeOfLong == 8)
+      {
+         // Long is stored as 8 bytes in index file, sizeof(long) = 4
+         Q_UINT32 ret_1;
+         Q_UINT32 ret_2;
+         COPY_DATA(&ret_1, sizeof(ret_1));
+         COPY_DATA(&ret_2, sizeof(ret_2));
+         if (!swapByteOrder)
+         {
+            // Index file order is the same as the order of this CPU.
+#if BYTE_ORDER == LITTLE_ENDIAN
+            // Index file order is little endian
+            ret = ret_1; // We drop the 4 most significant bytes
+#else
+            // Index file order is big endian
+            ret = ret_2; // We drop the 4 most significant bytes
+#endif
+         }
+         else
+         {
+            // Index file order is different from this CPU.
+#if BYTE_ORDER == LITTLE_ENDIAN
+            // Index file order is big endian
+            ret = ret_2; // We drop the 4 most significant bytes
+#else
+            // Index file order is little endian
+            ret = ret_1; // We drop the 4 most significant bytes
+#endif
+            // We swap the result to host order.
+            ret = kmail_swap_32(ret);
+         }
+         
+      }
       break;
     }
     g_chunk_offset += l;
@@ -817,34 +940,41 @@
         length += len2 + sizeof(short) + sizeof(MsgPartType); \
     } while(0)
 #define STORE_DATA(type, x) STORE_DATA_LEN(type, &x, sizeof(x))
+#if BYTE_ORDER == LITTLE_ENDIAN
+#warning Byte order is little endian (call swapEndian)
+#define SWAP_TO_NETWORK_ORDER(x) swapEndian(x)
+#else 
+#warning Byte order is big endian
+#define SWAP_TO_NETWORK_ORDER(x)
+#endif
   unsigned long tmp;
   QString tmp_str;
 
   //these is at the beginning because it is queried quite often
   tmp_str = msgIdMD5().stripWhiteSpace();
-  swapEndian(tmp_str);
+  SWAP_TO_NETWORK_ORDER(tmp_str);
   STORE_DATA_LEN(MsgIdMD5Part, tmp_str.unicode(), tmp_str.length() * 2);
   tmp = status();
   STORE_DATA(MsgStatusPart, tmp);
 
   //these are completely arbitrary order
   tmp_str = fromStrip().stripWhiteSpace();
-  swapEndian(tmp_str);
+  SWAP_TO_NETWORK_ORDER(tmp_str);
   STORE_DATA_LEN(MsgFromPart, tmp_str.unicode(), tmp_str.length() * 2);
   tmp_str = subject().stripWhiteSpace();
-  swapEndian(tmp_str);
+  SWAP_TO_NETWORK_ORDER(tmp_str);
   STORE_DATA_LEN(MsgSubjectPart, tmp_str.unicode(), tmp_str.length() * 2);
   tmp_str = toStrip().stripWhiteSpace();
-  swapEndian(tmp_str);
+  SWAP_TO_NETWORK_ORDER(tmp_str);
   STORE_DATA_LEN(MsgToPart, tmp_str.unicode(), tmp_str.length() * 2);
   tmp_str = replyToIdMD5().stripWhiteSpace();
-  swapEndian(tmp_str);
+  SWAP_TO_NETWORK_ORDER(tmp_str);
   STORE_DATA_LEN(MsgReplyToIdMD5Part, tmp_str.unicode(), tmp_str.length() * 2);
   tmp_str = xmark().stripWhiteSpace();
-  swapEndian(tmp_str);
+  SWAP_TO_NETWORK_ORDER(tmp_str);
   STORE_DATA_LEN(MsgXMarkPart, tmp_str.unicode(), tmp_str.length() * 2);
   tmp_str = fileName().stripWhiteSpace();
-  swapEndian(tmp_str);
+  SWAP_TO_NETWORK_ORDER(tmp_str);
   STORE_DATA_LEN(MsgFilePart, tmp_str.unicode(), tmp_str.length() * 2);
   tmp = msgSize();
   STORE_DATA(MsgSizePart, tmp);
Index: kmmsgdict.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmsgdict.cpp,v
retrieving revision 1.10
diff -u -r1.10 kmmsgdict.cpp
--- kmmsgdict.cpp	2002/01/04 11:06:28	1.10
+++ kmmsgdict.cpp	2002/02/02 02:05:36
@@ -15,10 +15,29 @@
 
 #include <errno.h>
 
+#include <config.h>
+
+#if HAVE_BYTESWAP_H
+#include <byteswap.h>
+#endif
+
+// We define functions as kmail_swap_NN so that we don't get compile errors
+// on platforms where bswap_NN happens to be a function instead of a define.
+
+/* Swap bytes in 32 bit value.  */
+#ifdef bswap_32
+#define kmail_swap_32(x) bswap_32(x)
+#else
+#define kmail_swap_32(x) \
+     ((((x) & 0xff000000) >> 24) | (((x) & 0x00ff0000) >>  8) |		      \
+      (((x) & 0x0000ff00) <<  8) | (((x) & 0x000000ff) << 24))
+#endif
+
+
 //-----------------------------------------------------------------------------
 
 // Current version of the .index.ids files
-#define IDS_VERSION 1001
+#define IDS_VERSION 1002
 
 // The asterisk at the end is important
 #define IDS_HEADER "# KMail-Index-IDs V%d\n*"
@@ -283,17 +302,27 @@
     fclose(fp);
     return -1;
   }
+
+  bool swapByteOrder;
+  Q_UINT32 byte_order;
+  if (!fread(&byte_order, sizeof(byte_order), 1, fp)) {
+    fclose(fp);
+    return -1;
+  }
+  swapByteOrder = (byte_order == 0x78563412);
   
-  int count;
+  Q_UINT32 count;
   if (!fread(&count, sizeof(count), 1, fp)) {
     fclose(fp);
     return -1;
   }
+  if (swapByteOrder)
+     count = kmail_swap_32(count);
 
   KMMsgDictREntry *rentry = new KMMsgDictREntry(count);
 
   for (int index = 0; index < count; index++) {
-    unsigned long msn;
+    Q_UINT32 msn;
 
     if (!fread(&msn, sizeof(msn), 1, fp)) {
       for (int i = 0; i < index; i++) {
@@ -304,6 +333,8 @@
       fclose(fp);
       return -1;
     }
+    if (swapByteOrder)
+       msn = kmail_swap_32(msn);
     
     //if (!msn)
       //kdDebug(5006) << "Dict found zero serial number in folder " << \
folder->label() << endl; @@ -366,8 +397,14 @@
   FILE *fp = rentry->fp;
 
   // kdDebug(5006) << "Dict writing for folder " << folder->label() << endl;
+  Q_UINT32 byteOrder = 0x12345678;
+  if (!fwrite(&byteOrder, sizeof(byteOrder), 1, fp)) {
+    kdDebug(5006) << "Dict cannot write byteOrder with folder " << folder->label() \
<< ": " +                  << strerror(errno) << " (" << errno << ")" << endl;
+    return -1;
+  }
   
-  int count = rentry->getRealSize();
+  Q_UINT32 count = rentry->getRealSize();
   if (!fwrite(&count, sizeof(count), 1, fp)) {
     kdDebug(5006) << "Dict cannot write count with folder " << folder->label() << ": \
"  << strerror(errno) << " (" << errno << ")" << endl;
@@ -375,7 +412,7 @@
   }
   
   for (int index = 0; index < count; index++) {
-    unsigned long msn = rentry->getMsn(index);
+    Q_UINT32 msn = rentry->getMsn(index);
     if (!fwrite(&msn, sizeof(msn), 1, fp))
       return -1;
   }


_______________________________________________
kmail Developers mailing list
kmail@mail.kde.org
http://mail.kde.org/mailman/listinfo/kmail

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic