--- libflatfile/MobileDB.cpp.orig	2003-06-19 19:37:46.000000000 -0400
+++ libflatfile/MobileDB.cpp	2007-07-10 06:33:33.000000000 -0400
@@ -213,7 +213,7 @@
         if (field == 0xFF) break;
 
         // Make sure that we don't go beyond the maximum number of fields.
-        if (field >= getMaxNumOfFields())
+        if (field > getMaxNumOfFields()) // css: chaanged >= to >
             throw PalmLib::error("maximum number of fields exceeded");
 
         // Expand the fields vector if this field goes beyond the end
@@ -302,7 +302,15 @@
     // Extract the field labels record.
     recNum = find_metadata_index(pdb, CATEGORY_FIELD_LABELS);
     mdb_record_t names = parse_record(pdb.getRecord(recNum));
-    numFields = names.size();
+
+    // css: Fields must have names, so zero-length field labels indicate
+    // fields that should be trimmed from the size.
+    int trim = 0;
+    for (mdb_record_t::reverse_iterator p = names.rbegin(); p < names.rend(); ++p) {
+        if ((*p).size() == 0)
+            ++trim;
+    }
+    numFields = names.size() - trim;
 
     // Extract the data types record.
     recNum = find_metadata_index(pdb, CATEGORY_DATA_TYPES);
@@ -321,7 +329,41 @@
     for (i = 0; i < numFields; ++i) {
         unsigned width;
 
-        appendField(names[i], Field::STRING);
+        // css: determine the field type
+        Field::FieldType fieldType;
+        switch (types[i][0]) {
+        case 's':
+        case 'T':
+        case 'P': // phone number
+        case 'M': // email address
+          fieldType = PalmLib::FlatFile::Field::STRING;
+          break;
+        case 'I':
+          fieldType = PalmLib::FlatFile::Field::INTEGER;
+          break;
+        case 'F':
+          fieldType = PalmLib::FlatFile::Field::FLOAT;
+          break;
+        case 'B':
+          fieldType = PalmLib::FlatFile::Field::BOOLEAN;
+          break;
+        case 'D':
+          fieldType = PalmLib::FlatFile::Field::DATE;
+          break;
+        case 'd':
+          fieldType = PalmLib::FlatFile::Field::TIME;
+          break;
+        case 'L':
+          fieldType = PalmLib::FlatFile::Field::LIST;
+          break;
+        case 'W':
+          fieldType = PalmLib::FlatFile::Field::LINK;
+          break;
+        default:
+          throw PalmLib::error("unknown field type");
+        }
+
+        appendField(names[i], fieldType);
         StrOps::convert_string(widths[i], width);
         lv.push_back(ListViewColumn(i, width));
     }
@@ -339,16 +381,64 @@
 
         // Extract the fields from the record.
         mdb_record_t fields = parse_record(pdb_record);
-        if (fields.size() != getNumOfFields())
+        if (fields.size() > getNumOfFields()) // css changed != to >
             throw PalmLib::error("data record has the wrong number of fields");
 
         // Insert the fields into the flat-file record.
+        // css: iterate over the types too.
         for (mdb_record_t::const_iterator p = fields.begin();
              p != fields.end(); ++p) {
             Field field;
 
-            field.type = Field::STRING;
-            field.v_string = (*p);
+            int fpos = p - fields.begin();
+            field.type = this->field_type(fpos);
+
+            switch (field.type) {
+            case Field::INTEGER:
+              StrOps::convert_string(*p, field.v_integer);
+              break;
+            case Field::FLOAT:
+              StrOps::convert_string(*p, field.v_float);
+              break;
+            case Field::DATE: {
+              pi_uint32_t daySince19040101 = 0;
+              StrOps::convert_string(*p, daySince19040101);
+              // Modified Julian to DMY calculation with an addition of 2415019
+              // http://www.codeproject.com/datetime/exceldmy.asp
+              // 2416481 is Julian Day for 1904-01-01
+              int l = daySince19040101 + 68569 + 2416481;
+              int n = int(( 4 * l ) / 146097);
+              l = l - int(( 146097 * n + 3 ) / 4);
+              int i = int(( 4000 * ( l + 1 ) ) / 1461001);
+              l = l - int(( 1461 * i ) / 4) + 31;
+              int j = int(( 80 * l ) / 2447);
+              int nDay = l - int(( 2447 * j ) / 80);
+              l = int(j / 11);
+              int nMonth = j + 2 - ( 12 * l );
+              int nYear = 100 * ( n - 49 ) + i + l;;
+              field.v_date.year = nYear;
+              field.v_date.month = nMonth;
+              field.v_date.day = nDay;
+              break;
+            }
+            case Field::TIME: {
+              pi_uint32_t seconds = 0;
+              StrOps::convert_string(*p, seconds);
+              field.v_time.hour = seconds / 3600;
+              field.v_time.minute = (seconds % 3600) / 60;
+              break;
+            }
+            case Field::BOOLEAN:
+              field.v_boolean = StrOps::string2boolean(*p);
+              break;
+            case Field::STRING:
+            case Field::LIST:
+            case Field::LINK:
+            default:
+              field.v_string = (*p);
+              break;
+            };
+
             record.appendField(field);
         }
 
@@ -412,8 +502,40 @@
     {
         mdb_record_t v;
 
-        for (i = 0; i < getMaxNumOfFields(); ++i)
-            v.push_back(std::string("str"));
+        for (i = 0; i < getMaxNumOfFields(); ++i) {
+            // css: add support for other field types.
+            if (i < getNumOfFields()) {
+            switch (field_type(i)) {
+            case Field::INTEGER:
+              v.push_back(std::string("I"));
+              break;
+            case Field::FLOAT:
+              v.push_back(std::string("F"));
+              break;
+            case Field::DATE:
+              v.push_back(std::string("D"));
+              break;
+            case Field::TIME:
+              v.push_back(std::string("d"));
+              break;
+            case Field::BOOLEAN:
+              v.push_back(std::string("B"));
+              break;
+            case Field::LIST:
+              v.push_back(std::string("L"));
+              break;
+            case Field::LINK:
+              v.push_back(std::string("W"));
+              break;
+            case Field::STRING:
+            default:
+              v.push_back(std::string("T"));
+              break;
+            };
+            } else {
+                v.push_back(std::string("T"));
+            }
+        }
         PalmLib::Record record(build_record(v));
         record.category(CATEGORY_DATA_TYPES);
         pdb.appendRecord(record);
@@ -452,11 +574,74 @@
         mdb_record_t v;
 
         for (unsigned int j = 0; j < getNumOfFields(); j++) {
+            // css: add support for other field types.
+#ifdef __LIBSTDCPP_PARTIAL_SUPPORT__
+			const Field field = record.fields()[j];
+#else
+			const Field field = record.fields().at(j);
+#endif
+            switch (field.type) {
+            case Field::INTEGER:
+            {
+              std::ostrstream stream;
+              stream << field.v_integer << std::ends;
+              v.push_back(stream.str());
+              break;
+            }
+            case Field::FLOAT:
+            {
+              std::ostrstream stream;
+              stream << field.v_float << std::ends;
+              v.push_back(stream.str());
+              break;
+            }
+            case Field::DATE:
+            {
+              // http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html
+              // http://www.codeproject.com/datetime/exceldmy.asp
+              pi_uint32_t daySince19040101 = 0;
+              pi_uint32_t y = field.v_date.year;
+              pi_uint32_t m = field.v_date.month;
+              pi_uint32_t d = field.v_date.day;
+              pi_uint32_t a = y /100;
+              pi_uint32_t b = a / 4;
+              pi_uint32_t c = 2 - a + b;
+              pi_uint32_t e = 365.25 * (y + 4716);
+              pi_uint32_t f = 30.6001 * (m + 1);
+              pi_uint32_t jd = c + d + e + f - 1524.5 - 2416481;
+              std::ostrstream stream;
+              stream << jd << std::ends;
+              v.push_back(stream.str());
+              break;
+            }
+            case Field::TIME:
+            {
+              std::ostrstream stream;
+              stream << ((field.v_time.hour * 3600) + (field.v_time.minute * 60)) << std::ends;
+              v.push_back(stream.str());
+              break;
+            }
+            case Field::BOOLEAN:
+            {
+              std::ostrstream stream;
+              stream << field.v_integer << std::ends;
+              v.push_back(field.v_boolean ? "1" : "0");
+              break;
+            }
+            case Field::LIST:
+            case Field::LINK:
+            case Field::STRING:
+            default:
+            {
+              v.push_back(field.v_string);
+              break;
+            }
 #ifdef __LIBSTDCPP_PARTIAL_SUPPORT__
-            v.push_back(record.fields()[j].v_string);
+//            v.push_back(record.fields()[j].v_string);
 #else
-            v.push_back(record.fields().at(j).v_string);
+//            v.push_back(record.fields().at(j).v_string);
 #endif
+            }
         }
 
         PalmLib::Record pdb_record(build_record(v));
@@ -476,6 +661,14 @@
 {
     switch (type) {
     case Field::STRING:
+    // css: add support for other field types.
+    case Field::INTEGER:
+    case Field::FLOAT:
+    case Field::DATE:
+    case Field::TIME:
+    case Field::BOOLEAN:
+    case Field::LIST:
+    case Field::LINK:
         return true;
     default:
         return false;