"Version 1.0, Copyright (C) 2000 by Helge Horch. All rights reserved. Published under the Squeak license, see for details. This software is provided on an ''as-is'' basis; use this software at your own risk. No warranty of fitness for any purpose is claimed, implicitly or otherwise. TO THE EXTENT PERMITTED BY LAW, THE AUTHOR SHALL NOT BE LIABLE TO USERS OF THE SOFTWARE FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS A RESULT OF USING, MODIFYING OR DISTRIBUTING THE SOFTWARE, OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF. "! Object subclass: #PDB instanceVariableNames: 'header filler appInfo entries exportUniqueIDs ' classVariableNames: '' poolDictionaries: '' category: 'PalmOS-Databases'! !PDB commentStamp: 'hh 5/21/2000 12:33' prior: 0! A PDB is the in-memory representation of a PalmOS(R) PDB or PRC database. It holds a header and a list of entries (the records/resources). Record indices start at 0 (zero).! !PDB methodsFor: 'testing' stamp: 'hh 5/21/2000 19:44'! hasAttribute: anInteger ^self attributes allMask: anInteger! ! !PDB methodsFor: 'testing' stamp: 'hh 5/21/2000 19:44'! isPDB ^self isPRC not! ! !PDB methodsFor: 'testing' stamp: 'hh 5/21/2000 12:11'! isPRC ^self hasAttribute: PDB dmHdrAttrResDB! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 15:55'! appInfo ^appInfo! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 15:55'! appInfo: aByteArray appInfo _ aByteArray! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:30'! attributes ^self headerFieldAt: 16r20 long: false! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:30'! attributes: anInteger self headerFieldAt: 16r20 put: anInteger long: false! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 12:59'! clearAttribute: anInteger self attributes: (self attributes bitClear: anInteger)! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:31'! creationDate "Answer the Date and the Time when the receiver was created." ^self dateAndTimeFromPilotSeconds: (self headerFieldAt: 16r24 long: true)! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:32'! creationDate: anArray "Set the receiver's creation date to the given Date and Time." self headerFieldAt: 16r24 put: (self pilotSecondsFromDateAndTime: anArray) long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 19:09'! creator ^PDB idStringOf: (self headerFieldAt: 16r40 long: true)! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:32'! creator: aString self headerFieldAt: 16r40 put: (PDB id: aString) long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:33'! lastBackupDate "Answer the Date and the Time when the receiver was last backed up." ^self dateAndTimeFromPilotSeconds: (self headerFieldAt: 16r2C long: true)! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:33'! lastBackupDate: anArray "Set the receiver's last backup date to the given Date and Time." self headerFieldAt: 16r2C put: (self pilotSecondsFromDateAndTime: anArray) long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:33'! modificationDate "Answer the Date and the Time when the receiver was last modified." ^self dateAndTimeFromPilotSeconds: (self headerFieldAt: 16r28 long: true)! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:33'! modificationDate: anArray "Set the receiver's last modification date to the given Date and Time." self headerFieldAt: 16r28 put: (self pilotSecondsFromDateAndTime: anArray) long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:34'! modificationNumber ^self headerFieldAt: 16r30 long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:34'! modificationNumber: anInteger self headerFieldAt: 16r30 put: anInteger long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 13:15'! name ^(self nameField copyUpTo: 0) asString! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 13:20'! name: aString aString size == 0 ifTrue: [self error: 'must use a non-empty name']. self nameField: ((ByteArray new: 32) replaceFrom: 1 to: (aString size min: 31) with: aString)! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:34'! nextRecordListID ^self headerFieldAt: 16r48 long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 13:43'! recordAt: anInteger ^entries at: anInteger+1! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 13:43'! recordAt: anInteger put: aPilotRecord ^entries at: anInteger+1 put: aPilotRecord! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 13:47'! recordCount "Since the receiver is the in-memory representation, answer the count as seen by the entries collection. New PDBs don't have the value in their header yet. But see recordCountField for completeness." ^entries size! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 12:58'! setAttribute: anInteger self attributes: (self attributes bitOr: anInteger)! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:35'! sortInfoAreaOffset ^self headerFieldAt: 16r38 long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 19:09'! type ^PDB idStringOf: (self headerFieldAt: 16r3C long: true)! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:35'! type: aString self headerFieldAt: 16r3C put: (PDB id: aString) long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:36'! uniqueIDSeed ^self headerFieldAt: 16r44 long: true! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:36'! version ^self headerFieldAt: 16r22 long: false! ! !PDB methodsFor: 'accessing' stamp: 'hh 5/21/2000 14:36'! version: anInteger self headerFieldAt: 16r22 put: anInteger long: false! ! !PDB methodsFor: 'enumerating' stamp: 'hh 5/21/2000 13:49'! recordsDo: aBlock "Evaluate the block for every record." entries do: aBlock! ! !PDB methodsFor: 'populating' stamp: 'hh 5/21/2000 13:48'! addRecord: aPilotRecord | index | index _ entries size. entries add: aPilotRecord. ^index! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 14:29'! appInfoAreaOffset ^self headerFieldAt: 16r34 long: true! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 16:46'! appInfoAreaOffset: anInteger ^self headerFieldAt: 16r34 put: anInteger long: true! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 12:31'! dateOffset "Answer the number of seconds between Jan 1, 1901 and Jan 1, 1904." ^94608000 "3*365*24*3600"! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 14:28'! headerFieldAt: anInteger long: aBoolean ^aBoolean ifTrue: [header unsignedLongAt: anInteger+1 bigEndian: true] ifFalse: [header unsignedShortAt: anInteger+1 bigEndian: true]! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 14:29'! headerFieldAt: anInteger put: valueInteger long: aBoolean aBoolean ifTrue: [header unsignedLongAt: anInteger+1 put: valueInteger bigEndian: true] ifFalse: [header unsignedShortAt: anInteger+1 put: valueInteger bigEndian: true]! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 14:20'! headerSize ^16r4E! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 13:11'! nameField "Answer an extracted ByteArray of the header's name field." ^header copyFrom: 1 to: 32! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 13:11'! nameField: aByteArray "Punch the given ByteArray over the header's name field." aByteArray size == 32 ifFalse: [self error: 'name field must consist of 32 bytes']. header replaceFrom: 1 to: 32 with: aByteArray! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 14:34'! recordCountField ^self headerFieldAt: 16r4C long: false! ! !PDB methodsFor: 'private' stamp: 'hh 5/21/2000 14:35'! recordCountField: anInteger self headerFieldAt: 16r4C put: anInteger long: false! ! !PDB methodsFor: 'converting' stamp: 'hh 5/21/2000 12:41'! dateAndTimeFromPilotSeconds: anInteger "Answer an Array of a Date and a Time corresponding to the the Pilot's notion of seconds since January 1, 1904. Note that Squeak's Date and Time class>>fromSeconds: start at 1901." ^Time dateAndTimeFromSeconds: anInteger + self dateOffset! ! !PDB methodsFor: 'converting' stamp: 'hh 5/21/2000 12:49'! pilotSecondsFromDateAndTime: anArray "Answer the PalmOS(R) date (seconds since 1904-01-01) from the given Date and Time." | secs | secs _ (anArray at: 1) asSeconds + (anArray at: 2) asSeconds. ^secs - self dateOffset! ! !PDB methodsFor: 'initializing' stamp: 'hh 5/21/2000 18:34'! exportUniqueIDs: aBoolean "Guards whether UniqueIDs will be exported as set in the records. Sending true is not recommended by the PDB spec, and false is the default anyway." exportUniqueIDs _ aBoolean! ! !PDB methodsFor: 'initializing' stamp: 'hh 5/21/2000 18:32'! initialize header _ ByteArray new: self headerSize. entries _ OrderedCollection new. filler _ nil. exportUniqueIDs _ false! ! !PDB methodsFor: 'importing' stamp: 'hh 5/21/2000 18:49'! import: aFileStream "Import the receiver's contents from the given stream. Does not close the stream afterwards!! Cf. #importFromFileNamed:" header _ aFileStream next: self headerSize. self isPRC ifTrue: [self importPRCProper: aFileStream] ifFalse: [self importPDBProper: aFileStream]! ! !PDB methodsFor: 'importing' stamp: 'hh 5/21/2000 18:26'! importAppInfoArea: aFileStream recordList: anArray | appInfoStart appInfoEnd | (appInfoStart _ self appInfoAreaOffset) > 0 ifTrue: [appInfoEnd _ anArray isEmpty ifTrue: [aFileStream size] ifFalse: [(anArray at: 1) at: 1]. "start of first record" aFileStream position = appInfoStart ifFalse: [filler _ aFileStream next: 2]. self appInfo: (aFileStream next: (appInfoEnd-appInfoStart))]! ! !PDB methodsFor: 'importing' stamp: 'hh 5/21/2000 18:08'! importChunk: aByteArray with: anArray resource: aBoolean | rec | rec _ PilotRecord new data: aByteArray. aBoolean ifTrue: [rec typeFromLong: (anArray at: 2); id: (anArray at: 3)] ifFalse: [rec attributes: (anArray at: 2); uniqueID: (anArray at: 3)]. self addRecord: rec! ! !PDB methodsFor: 'importing' stamp: 'hh 5/21/2000 15:13'! importChunks: anArray from: aFileStream resources: aBoolean | last entryStart entrySize data | last _ anArray size. anArray withIndexDo: [ :entry :i | entryStart _ entry at: 1. entrySize _ (i == last ifFalse: [(anArray at: i+1) at: 1] ifTrue: [aFileStream size]) - entryStart. aFileStream position: entryStart. data _ aFileStream next: entrySize. self importChunk: data with: entry resource: aBoolean]! ! !PDB methodsFor: 'importing' stamp: 'hh 5/21/2000 18:56'! importFromFileNamed: aString "Import the receiver from the given filename." | fs | fs _ (FileStream readOnlyFileNamed: aString) binary. self import: fs. fs close! ! !PDB methodsFor: 'importing' stamp: 'hh 5/21/2000 16:06'! importPDBProper: aFileStream | recList entry | recList _ (Array new: self recordCountField) collect: [ :dummy | entry _ aFileStream next: 8. Array with: (entry unsignedLongAt: 1 bigEndian: true) with: (entry at: 5) with: ((entry unsignedLongAt: 5 bigEndian: true) bitAnd: 16rFFFFFF)]. self importAppInfoArea: aFileStream recordList: recList. self importChunks: recList from: aFileStream resources: false! ! !PDB methodsFor: 'importing' stamp: 'hh 5/21/2000 18:26'! importPRCProper: aFileStream | recList entry | recList _ (Array new: self recordCountField) collect: [ :dummy | entry _ aFileStream next: 10. Array with: (entry unsignedLongAt: 7 bigEndian: true) with: (entry unsignedLongAt: 1 bigEndian: true) with: (entry unsignedShortAt: 5 bigEndian: true)]. self appInfoAreaOffset = 0 ifFalse: [self error: 'PRC files shouldn''t have an appInfoArea']. aFileStream position = recList first first ifFalse: [filler _ aFileStream next: 2]. self importChunks: recList from: aFileStream resources: true! ! !PDB methodsFor: 'exporting' stamp: 'hh 5/21/2000 19:18'! export: aFileStream "Export the receiver onto the given stream. Does not close the stream!! Cf. #exportToNewFileNamed:" | recStart | self recordCountField: self recordCount. recStart _ self headerSize + (self recordCount * (self isPRC ifTrue: [10] ifFalse: [8])) + (self hadFiller ifTrue: [filler size] ifFalse: [0]). self appInfo ifNotNil: [self isPRC ifTrue: [self error: 'PRC files shouldn''t have an appInfo area']. self appInfoAreaOffset: recStart. recStart _ recStart + (self appInfo size alignedTo: 2)]. "see below (odd filler)" aFileStream nextPutAll: header. self isPRC ifTrue: [self exportPRCList: aFileStream chunksFrom: recStart] ifFalse: [self exportPDBList: aFileStream chunksFrom: recStart]. self hadFiller ifTrue: [aFileStream nextPutAll: filler]. self appInfo ifNotNil: [aFileStream nextPutAll: self appInfo. appInfo size odd ifTrue: [aFileStream nextPut: 0]]. "is this really needed?" self exportRecords: aFileStream! ! !PDB methodsFor: 'exporting' stamp: 'hh 5/21/2000 18:00'! exportPDBList: aFileStream chunksFrom: anInteger | listEntry dataOfs | dataOfs _ anInteger. listEntry _ ByteArray new: 8. self recordsDo: [ :record | listEntry unsignedLongAt: 1 put: dataOfs bigEndian: true; unsignedLongAt: 5 put: (self exportedUniqueIDFor: record) bigEndian: true; at: 5 put: (record attributes bitAnd: 16rFF). aFileStream nextPutAll: listEntry. dataOfs _ dataOfs + record data size]! ! !PDB methodsFor: 'exporting' stamp: 'hh 5/21/2000 17:53'! exportPRCList: aFileStream chunksFrom: anInteger | listEntry dataOfs | dataOfs _ anInteger. listEntry _ ByteArray new: 10. self recordsDo: [ :record | listEntry unsignedLongAt: 7 put: dataOfs bigEndian: true; unsignedLongAt: 1 put: record typeAsLong bigEndian: true; unsignedShortAt: 5 put: record id bigEndian: true. aFileStream nextPutAll: listEntry. dataOfs _ dataOfs + record data size]! ! !PDB methodsFor: 'exporting' stamp: 'hh 5/21/2000 17:15'! exportRecords: aFileStream self recordsDo: [:each | aFileStream nextPutAll: each data]! ! !PDB methodsFor: 'exporting' stamp: 'hh 5/21/2000 18:56'! exportToNewFileNamed: aString "Export the receiver into the file with the given name." | fs | fs _ (FileStream newFileNamed: aString) binary. self export: fs. fs close ! ! !PDB methodsFor: 'exporting' stamp: 'hh 5/21/2000 18:35'! exportedUniqueIDFor: aPilotRecord "Exporting of preset uniqueIDs is not recommended. Use zero, the Pilot will generate its own." ^exportUniqueIDs ifTrue: [aPilotRecord uniqueID] ifFalse: [0]! ! !PDB methodsFor: 'exporting' stamp: 'hh 5/21/2000 18:25'! hadFiller "Answer whether two filler bytes after the record list were present on import." ^filler notNil! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! PDB class instanceVariableNames: ''! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:06'! dmHdrAttrAppInfoDirty ^4! ! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:06'! dmHdrAttrAttrBackup ^8! ! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:07'! dmHdrAttrCopyPrevention ^64! ! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:06'! dmHdrAttrOKToInstallNewer ^16! ! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:07'! dmHdrAttrOpen ^16r8000! ! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:06'! dmHdrAttrReadOnly ^2! ! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:06'! dmHdrAttrResDB ^1! ! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:07'! dmHdrAttrResetAfterInstall ^32! ! !PDB class methodsFor: 'attributes' stamp: 'hh 5/21/2000 12:07'! dmHdrAttrStream ^128! ! !PDB class methodsFor: 'type/creator' stamp: 'hh 5/21/2000 13:33'! id: aString "Answer the integer corresponding to the 4-character type/creator literal." "(PDB id: 'ABCD') hex" aString size = 4 ifFalse: [self error: 'IDs must consist of 4 characters']. ^aString asByteArray unsignedLongAt: 1 bigEndian: true! ! !PDB class methodsFor: 'type/creator' stamp: 'hh 5/21/2000 19:09'! idStringOf: anInteger "Answer the String representation of the given 4-byte creator/type id." ^(ByteArray new: 4) unsignedLongAt: 1 put: anInteger bigEndian: true; asString! ! !PDB class methodsFor: 'instance creation' stamp: 'hh 5/21/2000 14:04'! named: aString type: typeString creator: creatorString resource: aBoolean | now | now _ Time dateAndTimeNow. ^self new name: aString; type: typeString; creator: creatorString; creationDate: now; modificationDate: now; setAttribute: (aBoolean ifTrue: [PDB dmHdrAttrResDB] ifFalse: [0])! ! !PDB class methodsFor: 'instance creation' stamp: 'hh 5/21/2000 14:05'! new ^super new initialize! ! !PDB class methodsFor: 'examples' stamp: 'hh 5/21/2000 19:42'! examples "You must supply real PDB and PRC files. Adjust the filenames accordingly." "Import the Memo database and examine the records. Provided you use a real MemoDB, you can see the memo's text in the Explorer by selecting a record and printing 'self data asString' in the lower pane. Note that all records end in '0 asCharacter'..." (PDB new importFromFileNamed: 'MemoDB.pdb') explore. "Import a PalmOS(R) application and examine its resources" (PDB new importFromFileNamed: 'Year.prc') explore. "Create a very simple PDB. Note the 'false' parameter to resource:..." (PDB named: 'My first PDB' type: 'HELL' creator: 'WORL' resource: false) addRecord: (PilotRecord new data: 'Hello, world.'; attributes: 0); exportToNewFileNamed: 'MyPDB.pdb'. "Reopen it and examine its contents." (PDB new importFromFileNamed: 'MyPDB.pdb') explore. "Create a very simple PRC. Do not sync that one to a real Pilot." (PDB named: 'My first PRC' type: 'HELL' creator: 'WORL' resource: true) addRecord: (PilotRecord new type: 'NONS'; id: 101; data: 'Hello, world.'); exportToNewFileNamed: 'MyPRC.prc'. "Reopen it and examine its contents." (PDB new importFromFileNamed: 'MyPRC.prc') explore. "Copy a PDB. Note that uniqueIDs will be cleared on export, as recommended by the PDB spec." (PDB new importFromFileNamed: 'MemoDB.pdb') exportToNewFileNamed: 'Copied', 'MemoDB.pdb'. "Copy a PRC. PRCs don't have uniqueIDs, so the result should be bit-identical." (PDB new importFromFileNamed: 'Year.prc') exportToNewFileNamed: 'Copied', 'Year.prc'. "Copy a PDB verbatim, preserving the uniqueIDs. Included for completeness to show bit-identicalness is possible. Remember that uniqueIDs *should* be cleared on export, as recommended by the PDB spec. Don't confuse your Pilot. " (PDB new importFromFileNamed: 'MemoDB.pdb') exportUniqueIDs: true; exportToNewFileNamed: 'VerbatimCopied', 'MemoDB.pdb'! ! Object subclass: #PilotRecord instanceVariableNames: 'chunk attrs uniqueID id type ' classVariableNames: '' poolDictionaries: '' category: 'PalmOS-Databases'! !PilotRecord commentStamp: 'hh 5/21/2000 19:43' prior: 0! A PilotRecord lives either in a PDB or a PRC. It carries a ByteArray as its data. When it is a PDB record, it has attributes and a UniqueID. As a PRC record, it has a resource name (like 'code', expressed as an unsigned long) and an ID (SmallInteger).! !PilotRecord methodsFor: 'accessing' stamp: 'hh 5/21/2000 15:21'! data ^chunk! ! !PilotRecord methodsFor: 'accessing' stamp: 'hh 5/21/2000 15:20'! data: aByteArray chunk _ aByteArray! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 19:26'! attributes ^attrs ifNil: [attrs _ 0]! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 15:20'! attributes: aSmallInteger attrs _ aSmallInteger! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 18:13'! bePublic self clearAttribute: PilotRecord dmRecAttrSecret! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 18:13'! beSecret self setAttribute: PilotRecord dmRecAttrSecret! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 16:50'! category ^self attributes bitAnd: PilotRecord dmRecAttrCategoryMask! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 16:54'! category: aSmallInteger ^self attributes: ((self attributes bitAnd: PilotRecord dmAllRecAttrs) bitOr: (aSmallInteger bitAnd: PilotRecord dmRecAttrCategoryMask))! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 16:57'! clearAttribute: aSmallInteger self attributes: (self attributes bitClear: (aSmallInteger bitAnd: PilotRecord dmAllRecAttrs))! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 18:16'! hasAttributes: aSmallInteger ^self attributes allMask: aSmallInteger! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 18:16'! isSecret ^self hasAttributes: PilotRecord dmRecAttrSecret! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 18:11'! markForArchival "Archive receiving record on next HotSync." self setAttribute: PilotRecord dmRecAttrDirty! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 18:10'! markForDeletion "Delete receiving record on next HotSync." self setAttribute: PilotRecord dmRecAttrDelete! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 16:56'! setAttribute: aSmallInteger self attributes: (self attributes bitOr: (aSmallInteger bitAnd: PilotRecord dmAllRecAttrs))! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 15:22'! uniqueID ^uniqueID! ! !PilotRecord methodsFor: 'record nature' stamp: 'hh 5/21/2000 18:15'! uniqueID: anInteger "UniqueIDs may be assigned, but will not be exported because that's not recommended by the spec. Unless you change (or subclass) PDB>>exportedUniqueIDFor:" uniqueID _ anInteger! ! !PilotRecord methodsFor: 'resource nature' stamp: 'hh 5/21/2000 15:22'! id ^id! ! !PilotRecord methodsFor: 'resource nature' stamp: 'hh 5/21/2000 15:23'! id: aSmallInteger id _ aSmallInteger! ! !PilotRecord methodsFor: 'resource nature' stamp: 'hh 5/21/2000 19:10'! type ^PDB idStringOf: type! ! !PilotRecord methodsFor: 'resource nature' stamp: 'hh 5/21/2000 16:30'! type: aString type _ PDB id: aString! ! !PilotRecord methodsFor: 'resource nature' stamp: 'hh 5/21/2000 17:53'! typeAsLong ^type! ! !PilotRecord methodsFor: 'resource nature' stamp: 'hh 5/21/2000 18:07'! typeFromLong: anInteger type _ anInteger! ! !PilotRecord methodsFor: 'testing' stamp: 'hh 5/21/2000 15:24'! isRecord ^attrs notNil and: [uniqueID notNil]! ! !PilotRecord methodsFor: 'testing' stamp: 'hh 5/21/2000 15:24'! isResource ^type notNil and: [id notNil]! ! !PilotRecord methodsFor: 'printing' stamp: 'hh 5/21/2000 16:29'! printOn: aStream self isResource ifTrue: [aStream nextPutAll: self type printString; nextPut: $(; nextPutAll: self id printString; nextPut: $)] ifFalse: [super printOn: aStream]! ! "-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- "! PilotRecord class instanceVariableNames: ''! !PilotRecord class methodsFor: 'record attributes' stamp: 'hh 5/21/2000 16:51'! dmAllRecAttrs ^16rF0! ! !PilotRecord class methodsFor: 'record attributes' stamp: 'hh 5/21/2000 16:49'! dmRecAttrBusy ^16r20! ! !PilotRecord class methodsFor: 'record attributes' stamp: 'hh 5/21/2000 16:49'! dmRecAttrCategoryMask ^16r0F! ! !PilotRecord class methodsFor: 'record attributes' stamp: 'hh 5/21/2000 16:49'! dmRecAttrDelete ^16r80! ! !PilotRecord class methodsFor: 'record attributes' stamp: 'hh 5/21/2000 16:49'! dmRecAttrDirty ^16r40! ! !PilotRecord class methodsFor: 'record attributes' stamp: 'hh 5/21/2000 16:48'! dmRecAttrSecret ^16r10! !