Ticket #12257: patch-libflatfile-MobileDB.cpp.diff

File patch-libflatfile-MobileDB.cpp.diff, 9.4 KB (added by cssdev, 17 years ago)

add MobileDB 4 read and write support

  • libflatfile/MobileDB.cpp

    old new  
    213213        if (field == 0xFF) break;
    214214
    215215        // Make sure that we don't go beyond the maximum number of fields.
    216         if (field >= getMaxNumOfFields())
     216        if (field > getMaxNumOfFields()) // css: chaanged >= to >
    217217            throw PalmLib::error("maximum number of fields exceeded");
    218218
    219219        // Expand the fields vector if this field goes beyond the end
     
    302302    // Extract the field labels record.
    303303    recNum = find_metadata_index(pdb, CATEGORY_FIELD_LABELS);
    304304    mdb_record_t names = parse_record(pdb.getRecord(recNum));
    305     numFields = names.size();
     305
     306    // css: Fields must have names, so zero-length field labels indicate
     307    // fields that should be trimmed from the size.
     308    int trim = 0;
     309    for (mdb_record_t::reverse_iterator p = names.rbegin(); p < names.rend(); ++p) {
     310        if ((*p).size() == 0)
     311            ++trim;
     312    }
     313    numFields = names.size() - trim;
    306314
    307315    // Extract the data types record.
    308316    recNum = find_metadata_index(pdb, CATEGORY_DATA_TYPES);
     
    321329    for (i = 0; i < numFields; ++i) {
    322330        unsigned width;
    323331
    324         appendField(names[i], Field::STRING);
     332        // css: determine the field type
     333        Field::FieldType fieldType;
     334        switch (types[i][0]) {
     335        case 's':
     336        case 'T':
     337        case 'P': // phone number
     338        case 'M': // email address
     339          fieldType = PalmLib::FlatFile::Field::STRING;
     340          break;
     341        case 'I':
     342          fieldType = PalmLib::FlatFile::Field::INTEGER;
     343          break;
     344        case 'F':
     345          fieldType = PalmLib::FlatFile::Field::FLOAT;
     346          break;
     347        case 'B':
     348          fieldType = PalmLib::FlatFile::Field::BOOLEAN;
     349          break;
     350        case 'D':
     351          fieldType = PalmLib::FlatFile::Field::DATE;
     352          break;
     353        case 'd':
     354          fieldType = PalmLib::FlatFile::Field::TIME;
     355          break;
     356        case 'L':
     357          fieldType = PalmLib::FlatFile::Field::LIST;
     358          break;
     359        case 'W':
     360          fieldType = PalmLib::FlatFile::Field::LINK;
     361          break;
     362        default:
     363          throw PalmLib::error("unknown field type");
     364        }
     365
     366        appendField(names[i], fieldType);
    325367        StrOps::convert_string(widths[i], width);
    326368        lv.push_back(ListViewColumn(i, width));
    327369    }
     
    339381
    340382        // Extract the fields from the record.
    341383        mdb_record_t fields = parse_record(pdb_record);
    342         if (fields.size() != getNumOfFields())
     384        if (fields.size() > getNumOfFields()) // css changed != to >
    343385            throw PalmLib::error("data record has the wrong number of fields");
    344386
    345387        // Insert the fields into the flat-file record.
     388        // css: iterate over the types too.
    346389        for (mdb_record_t::const_iterator p = fields.begin();
    347390             p != fields.end(); ++p) {
    348391            Field field;
    349392
    350             field.type = Field::STRING;
    351             field.v_string = (*p);
     393            int fpos = p - fields.begin();
     394            field.type = this->field_type(fpos);
     395
     396            switch (field.type) {
     397            case Field::INTEGER:
     398              StrOps::convert_string(*p, field.v_integer);
     399              break;
     400            case Field::FLOAT:
     401              StrOps::convert_string(*p, field.v_float);
     402              break;
     403            case Field::DATE: {
     404              pi_uint32_t daySince19040101 = 0;
     405              StrOps::convert_string(*p, daySince19040101);
     406              // Modified Julian to DMY calculation with an addition of 2415019
     407              // http://www.codeproject.com/datetime/exceldmy.asp
     408              // 2416481 is Julian Day for 1904-01-01
     409              int l = daySince19040101 + 68569 + 2416481;
     410              int n = int(( 4 * l ) / 146097);
     411              l = l - int(( 146097 * n + 3 ) / 4);
     412              int i = int(( 4000 * ( l + 1 ) ) / 1461001);
     413              l = l - int(( 1461 * i ) / 4) + 31;
     414              int j = int(( 80 * l ) / 2447);
     415              int nDay = l - int(( 2447 * j ) / 80);
     416              l = int(j / 11);
     417              int nMonth = j + 2 - ( 12 * l );
     418              int nYear = 100 * ( n - 49 ) + i + l;;
     419              field.v_date.year = nYear;
     420              field.v_date.month = nMonth;
     421              field.v_date.day = nDay;
     422              break;
     423            }
     424            case Field::TIME: {
     425              pi_uint32_t seconds = 0;
     426              StrOps::convert_string(*p, seconds);
     427              field.v_time.hour = seconds / 3600;
     428              field.v_time.minute = (seconds % 3600) / 60;
     429              break;
     430            }
     431            case Field::BOOLEAN:
     432              field.v_boolean = StrOps::string2boolean(*p);
     433              break;
     434            case Field::STRING:
     435            case Field::LIST:
     436            case Field::LINK:
     437            default:
     438              field.v_string = (*p);
     439              break;
     440            };
     441
    352442            record.appendField(field);
    353443        }
    354444
     
    412502    {
    413503        mdb_record_t v;
    414504
    415         for (i = 0; i < getMaxNumOfFields(); ++i)
    416             v.push_back(std::string("str"));
     505        for (i = 0; i < getMaxNumOfFields(); ++i) {
     506            // css: add support for other field types.
     507            if (i < getNumOfFields()) {
     508            switch (field_type(i)) {
     509            case Field::INTEGER:
     510              v.push_back(std::string("I"));
     511              break;
     512            case Field::FLOAT:
     513              v.push_back(std::string("F"));
     514              break;
     515            case Field::DATE:
     516              v.push_back(std::string("D"));
     517              break;
     518            case Field::TIME:
     519              v.push_back(std::string("d"));
     520              break;
     521            case Field::BOOLEAN:
     522              v.push_back(std::string("B"));
     523              break;
     524            case Field::LIST:
     525              v.push_back(std::string("L"));
     526              break;
     527            case Field::LINK:
     528              v.push_back(std::string("W"));
     529              break;
     530            case Field::STRING:
     531            default:
     532              v.push_back(std::string("T"));
     533              break;
     534            };
     535            } else {
     536                v.push_back(std::string("T"));
     537            }
     538        }
    417539        PalmLib::Record record(build_record(v));
    418540        record.category(CATEGORY_DATA_TYPES);
    419541        pdb.appendRecord(record);
     
    452574        mdb_record_t v;
    453575
    454576        for (unsigned int j = 0; j < getNumOfFields(); j++) {
     577            // css: add support for other field types.
     578#ifdef __LIBSTDCPP_PARTIAL_SUPPORT__
     579                        const Field field = record.fields()[j];
     580#else
     581                        const Field field = record.fields().at(j);
     582#endif
     583            switch (field.type) {
     584            case Field::INTEGER:
     585            {
     586              std::ostrstream stream;
     587              stream << field.v_integer << std::ends;
     588              v.push_back(stream.str());
     589              break;
     590            }
     591            case Field::FLOAT:
     592            {
     593              std::ostrstream stream;
     594              stream << field.v_float << std::ends;
     595              v.push_back(stream.str());
     596              break;
     597            }
     598            case Field::DATE:
     599            {
     600              // http://quasar.as.utexas.edu/BillInfo/JulianDatesG.html
     601              // http://www.codeproject.com/datetime/exceldmy.asp
     602              pi_uint32_t daySince19040101 = 0;
     603              pi_uint32_t y = field.v_date.year;
     604              pi_uint32_t m = field.v_date.month;
     605              pi_uint32_t d = field.v_date.day;
     606              pi_uint32_t a = y /100;
     607              pi_uint32_t b = a / 4;
     608              pi_uint32_t c = 2 - a + b;
     609              pi_uint32_t e = 365.25 * (y + 4716);
     610              pi_uint32_t f = 30.6001 * (m + 1);
     611              pi_uint32_t jd = c + d + e + f - 1524.5 - 2416481;
     612              std::ostrstream stream;
     613              stream << jd << std::ends;
     614              v.push_back(stream.str());
     615              break;
     616            }
     617            case Field::TIME:
     618            {
     619              std::ostrstream stream;
     620              stream << ((field.v_time.hour * 3600) + (field.v_time.minute * 60)) << std::ends;
     621              v.push_back(stream.str());
     622              break;
     623            }
     624            case Field::BOOLEAN:
     625            {
     626              std::ostrstream stream;
     627              stream << field.v_integer << std::ends;
     628              v.push_back(field.v_boolean ? "1" : "0");
     629              break;
     630            }
     631            case Field::LIST:
     632            case Field::LINK:
     633            case Field::STRING:
     634            default:
     635            {
     636              v.push_back(field.v_string);
     637              break;
     638            }
    455639#ifdef __LIBSTDCPP_PARTIAL_SUPPORT__
    456             v.push_back(record.fields()[j].v_string);
     640//            v.push_back(record.fields()[j].v_string);
    457641#else
    458             v.push_back(record.fields().at(j).v_string);
     642//            v.push_back(record.fields().at(j).v_string);
    459643#endif
     644            }
    460645        }
    461646
    462647        PalmLib::Record pdb_record(build_record(v));
     
    476661{
    477662    switch (type) {
    478663    case Field::STRING:
     664    // css: add support for other field types.
     665    case Field::INTEGER:
     666    case Field::FLOAT:
     667    case Field::DATE:
     668    case Field::TIME:
     669    case Field::BOOLEAN:
     670    case Field::LIST:
     671    case Field::LINK:
    479672        return true;
    480673    default:
    481674        return false;