[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 6:11:48
[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... the previous version screwed up the .ids files rather badly.... this one 
should be better.

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

["kmail.portable2.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 06:08:06
@@ -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 06:08:08
@@ -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 06:08:15
@@ -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 06:08:18
@@ -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 06:08:19
@@ -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*"
@@ -46,6 +65,8 @@
     for (int i = 0; i < size; i++)
       array.at(i) = 0;
     fp = NULL;
+    swapByteOrder = false;
+    baseOffset = 0;
   }
   
   ~KMMsgDictREntry()
@@ -103,6 +124,8 @@
 public:
   QMemArray<KMMsgDictEntry *> array;
   FILE *fp;
+  bool swapByteOrder;
+  int baseOffset;
 };
 
 //-----------------------------------------------------------------------------
@@ -283,20 +306,30 @@
     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;
+  for (unsigned int index = 0; index < count; index++) {
+    Q_UINT32 msn;
 
     if (!fread(&msn, sizeof(msn), 1, fp)) {
-      for (int i = 0; i < index; i++) {
+      for (unsigned int i = 0; i < index; i++) {
         msn = rentry->getMsn(i);
         dict->remove((long)msn);
       }
@@ -304,7 +337,10 @@
       fclose(fp);
       return -1;
     }
-    
+    if (swapByteOrder)
+       msn = kmail_swap_32(msn);
+
+qWarning("Serial number = %d", msn);    
     //if (!msn)
       //kdDebug(5006) << "Dict found zero serial number in folder " << \
folder->label() << endl;  
@@ -334,25 +370,44 @@
   
   if (!rentry->fp) {
     QString filename = getFolderIdsLocation(folder);
-    rentry->fp = fopen(filename.local8Bit(), "r+");
-    if (!rentry->fp)
-      rentry->fp = fopen(filename.local8Bit(), "w+");
+    FILE *fp = fopen(filename.local8Bit(), "r+");
+    if (fp)
+    {
+      int version = 0;
+      fscanf(fp, IDS_HEADER, &version);
+      if (version == IDS_VERSION) 
+      {
+         Q_UINT32 byte_order = 0;
+         fread(&byte_order, sizeof(byte_order), 1, fp);
+         rentry->swapByteOrder = (byte_order == 0x78563412);
+      }
+      else
+      {
+         fclose(fp);
+         fp = 0;
+      }
+    }
+
+    if (!fp)
+    {
+      fp = fopen(filename.local8Bit(), "w+");
+      if (!fp)
+      {
+        kdDebug(5006) << "Dict cannot open with folder " << folder->label() << ": "
+                      << strerror(errno) << " (" << errno << ")" << endl;
+         delete rentry;
+         rentry = 0;
+         return 0;         
+      }
+      fprintf(fp, IDS_HEADER, IDS_VERSION);
+      Q_UINT32 byteOrder = 0x12345678;
+      fwrite(&byteOrder, sizeof(byteOrder), 1, fp);
+      rentry->swapByteOrder = false;
+    }
+    rentry->baseOffset = ftell(fp);
+    rentry->fp = fp;
   }
   
-  if (rentry->fp) {
-    FILE *fp = rentry->fp;
-    rewind(fp);
-    
-    fprintf(fp, IDS_HEADER, IDS_VERSION);
-    if (ferror(fp))
-      rentry = 0;
-      
-  } else {
-    kdDebug(5006) << "Dict cannot open with folder " << folder->label() << ": "
-                  << strerror(errno) << " (" << errno << ")" << endl;
-    rentry = 0;
-  }
-    
   return rentry;
 }
 
@@ -365,17 +420,17 @@
     return 0;
   FILE *fp = rentry->fp;
 
+  fseek(fp, rentry->baseOffset, SEEK_SET);
   // kdDebug(5006) << "Dict writing for folder " << folder->label() << endl;
-  
-  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;
     return -1;
   }
   
-  for (int index = 0; index < count; index++) {
-    unsigned long msn = rentry->getMsn(index);
+  for (unsigned int index = 0; index < count; index++) {
+    Q_UINT32 msn = rentry->getMsn(index);
     if (!fwrite(&msn, sizeof(msn), 1, fp))
       return -1;
   }
@@ -410,14 +465,21 @@
   
 //  kdDebug(5006) << "Dict appending for folder " << folder->label() << endl;
   
-  int count;
+  fseek(fp, rentry->baseOffset, SEEK_SET);
+  Q_UINT32 count;
   if (!fread(&count, sizeof(count), 1, fp)) {
     kdDebug(5006) << "Dict cannot read count for folder " << folder->label() << ": "
                   << strerror(errno) << " (" << errno << ")" << endl;
     return 0;
   }
+  if (rentry->swapByteOrder)
+     kmail_swap_32(count);
+  
   count++;
-  fseek(fp, -4, SEEK_CUR);
+
+  if (rentry->swapByteOrder)
+     kmail_swap_32(count);
+  fseek(fp, rentry->baseOffset, SEEK_SET);
   if (!fwrite(&count, sizeof(count), 1, fp)) {
     kdDebug(5006) << "Dict cannot write count for folder " << folder->label() << ": \
"  << strerror(errno) << " (" << errno << ")" << endl;
@@ -428,7 +490,7 @@
   if (ofs > 0)
     fseek(rentry->fp, ofs, SEEK_CUR);
 
-  ulong msn = rentry->getMsn(index);
+  Q_UINT32 msn = rentry->getMsn(index);
   if (!fwrite(&msn, sizeof(msn), 1, rentry->fp)) {
     kdDebug(5006) << "Dict cannot write count for folder " << folder->label() << ": \
"  << strerror(errno) << " (" << errno << ")" << endl;


_______________________________________________
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