' This program is an example of reading the memopad.dat file ' produced by the Palm Pilot pc-based software. The file is a ' MSFC streams file that 3Com warns will MOST LIKELY change in ' structure in future releases. You have been warned . ' By: Scott Leighton Jan 2, 1999 ' Permission granted to freely distribute provided that no ' money changes hands, otherwise contact me: helphand@pacbell.net ' copyright$ = "Copyright 1999, Scott Leighton email:helphand@pacbell.net" ' declare variables DEFINT A-Z DIM SHARED MyShort AS DOUBLE, mylong AS DOUBLE, cslen AS DOUBLE, csl1 AS DOUBLE, csl2 AS DOUBLE, csl3 AS DOUBLE, csl4 AS DOUBLE DIM SHARED lo AS DOUBLE, lo1 AS DOUBLE, lo2 AS DOUBLE, hi AS DOUBLE ' open memopad a$ = "memopad.dat" OPEN a$ FOR BINARY AS #1 ' now read the file and convert the structure to a usable ' format for qbasic. ' Read the tag fields GOSUB GetByte: Tag1 = a GOSUB GetByte: Tag2 = a GOSUB GetChar: Tag3$ = a$ GOSUB GetChar: Tag4$ = a$ PRINT "Tag field values are: " PRINT " Tag 1 =", Tag1 PRINT " Tag 2 =", Tag2 PRINT " Tag 3 =", Tag3$ PRINT " Tag 4 =", Tag4$ PRINT "Hit any key to continue to next field" a$ = INPUT$(1) ' Read the General Header fields GOSUB GetByte: cslen = a GOSUB GetStrg PRINT "General Header field values are: " PRINT " cslen =", cslen PRINT " string =", a$ PRINT "Hit any key to continue to next field" a$ = INPUT$(1) ' Read the Show Header Fields (if zero in first byte, NO show header) GOSUB GetByte: cslen = a GOSUB GetStrg: PRINT "Show Header field values are: " PRINT " cslen =", cslen PRINT " string =", a$ PRINT "Hit any key to continue to next field" a$ = INPUT$(1) ' Read the Category Header Fields GOSUB GetLong: mylong = cslen PRINT "Category Header field values are: " PRINT " unknown =", cslen GOSUB GetLong: mylong = cslen PRINT " # categories =", cslen categories = cslen PRINT "Hit any key to continue to next field" a$ = INPUT$(1) WHILE categories > 0 categories = categories - 1 GOSUB GetLong: PRINT " index =", cslen GOSUB GetLong: PRINT " id =", cslen GOSUB GetLong: PRINT " name dirty flg =", cslen GOSUB GetByte: cslen = a: PRINT " cslen =", cslen GOSUB GetStrg: PRINT " Short name =", a$ GOSUB GetByte: cslen = a: PRINT " cslen =", cslen GOSUB GetStrg: PRINT " Long name =", a$ PRINT "Hit any key to continue to next field" a$ = INPUT$(1) WEND ' Read the Table Header (schema) fields GOSUB GetLong: mylong = cslen PRINT "Table Header field values are: " PRINT " unknown =", cslen GOSUB GetLong: mylong = cslen PRINT " # fields =", cslen GOSUB GetLong: mylong = cslen PRINT " unknown =", cslen GOSUB GetLong: mylong = cslen PRINT " unknown =", cslen GOSUB GetLong: mylong = cslen PRINT " unknown =", cslen GOSUB GetShort: mylong = cslen PRINT " # fields =", cslen tableentries = cslen PRINT "Hit any key to continue to next field" a$ = INPUT$(1) IF tableentries > 0 THEN FOR j = 1 TO tableentries GOSUB GetShort: mylong = cslen PRINT " field "; j; " type =", cslen PRINT "Hit any key to continue to next field" a$ = INPUT$(1) NEXT j END IF ' Read the Number of Entries field GOSUB GetLong: mylong = cslen PRINT "Number of Entries field values are: " PRINT " # entries * 6 =", cslen memoentries = cslen / 6 PRINT " or "; memoentries; " actual memo pad entries" PRINT "Hit any key to continue to the memo pad entries" a$ = INPUT$(1) ' Now iterate over the file reading the number of entries we found ' above IF memoentries > 0 THEN FOR j = 1 TO memoentries PRINT "** Memopad Entry #"; j; " **" GOSUB GetLong: mylong = cslen PRINT " field type =", cslen; GOSUB GetLong: mylong = cslen PRINT " record id =", cslen GOSUB GetLong: mylong = cslen PRINT " field type =", cslen; GOSUB GetLong: mylong = cslen PRINT " status =", cslen GOSUB GetLong: mylong = cslen PRINT " field type =", cslen; GOSUB GetLong: mylong = cslen PRINT " position =", cslen GOSUB GetLong: mylong = cslen PRINT " field type =", cslen; GOSUB GetLong: mylong = cslen PRINT " always zero =", cslen PRINT "Hit any key to continue to memo text field (may be long display)" a$ = INPUT$(1) GOSUB GetByte: cslen = a: PRINT " cslen =", cslen GOSUB GetStrg: PRINT " Memo Text =", a$ PRINT "Hit any key to continue to next field" a$ = INPUT$(1) GOSUB GetLong: mylong = cslen PRINT " field type =", cslen; GOSUB GetLong: mylong = cslen PRINT " private =", cslen GOSUB GetLong: mylong = cslen PRINT " field type =", cslen; GOSUB GetLong: mylong = cslen PRINT " category =", cslen PRINT "Hit any key to continue to next field" a$ = INPUT$(1) NEXT j END IF ' We're done and should be a eof at this point CLOSE 1 END ' ' ' Support routines to convert shorts, longs, bytes and strings ' ' ' Gets a byte and returns the integer value of the byte GetByte: a$ = " ": GET #1, , a$: a = ASC(a$): RETURN ' Gets a byte and returns the actual char GetChar: a$ = " ": GET #1, , a$: RETURN ' Gets a cstring, assumes the cslen has ALREADY been loaded with ' the FIRST BYTE ONLY of the cstring structure GetStrg: b$ = "" ' if first byte is 0xFF then length follows in a short IF cslen = 255 THEN GOSUB GetShort: ELSE ' if first byte is zero, then string has zero length, return null string IF cslen = 0 THEN a$ = "": RETURN END IF END IF ' Read number of characters that we determined from above (cslen) FOR i = 1 TO cslen: GOSUB GetByte: b$ = b$ + a$: NEXT i a$ = b$ RETURN ' Get a short, return the integer value of the short - shorts are ' stored in low byte, high byte order GetShort: GOSUB GetByte: lo = a GOSUB GetByte: hi = a cslen = (hi * 256) + lo RETURN ' Get a long, return the floating point value since it's potentially ' such a large number. Qbasic will barf if we don't use doubles ' note that a long is also stored in lowest to highest byte order GetLong: GOSUB GetByte: lo = a GOSUB GetByte: lo1 = a GOSUB GetByte: lo2 = a GOSUB GetByte: hi = a csl1 = lo csl2 = lo1 * 256 csl3 = lo2 * 65536 csl4 = hi * 16777216 cslen = csl1 + csl2 + csl3 + csl4 RETURN