17133 lines
456 KiB
Plaintext
Executable File
17133 lines
456 KiB
Plaintext
Executable File
SIBO 'C' Software Development Kit
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Version 2.30
|
||
|
||
|
||
March 1, 1999
|
||
|
||
|
||
(C) Copyright Psion PLC 1990-98
|
||
|
||
|
||
All rights reserved. This manual and the programs referred to herein are copyrighted works of Psion PLC,
|
||
London, England. Reproduction in whole or in part, including utilization in machines capable of
|
||
reproduction or retrieval, without express written permission of Psion PLC, is prohibited. Reverse
|
||
engineering is also prohibited.
|
||
|
||
|
||
The information in this document is subject to change without notice.
|
||
|
||
|
||
Psion and the Psion logo are registered trademarks, and Psion, Psion MC, Psion HC, Psion Series 3, Psion
|
||
Series 3a and Psion Workabout are trademarks of Psion PLC.
|
||
|
||
|
||
TopSpeed is a registered trademark of Clarion Software Corporation. Intel 8086 and 80286 are registered
|
||
trademarks of Intel Corporation. IBM, IBM XT and IBM AT are registered trademarks of International
|
||
Business Machines Corp. Microsoft and MS-DOS are registered trademarks of Microsoft Corporation.
|
||
Apple and Macintosh are registered trademarks of Apple Computer Inc. VAX and VMS are registered
|
||
trademarks of Digital Equipment Corporation. Brief is a registered trademark of Underware Inc. Psion
|
||
PLC acknowledges that some other names referred to are registered trademarks.
|
||
|
||
|
||
CONTENTS
|
||
|
||
|
||
1 Introduction.............sccsccsssscrssersserscsresesceeeeseceseesssesseseseesseesseesseesseessesssessceescesscesscssscesseseseesonees 1-1
|
||
sits: OE IB Classesic. 7 scp beet eSegl ocd sdee hand tego eck snug bantstes’ cet ocep sant tact eetouepbantstgecboreeitabetes 1-2
|
||
|
||
Notation se: cscccteaseasteessdsatcaesiseb cesedsas ceceuahtecsvica secuvdcnbecuvdene cevyachncebavicardcsbidandees dendenvccnneebvess 1-2
|
||
|
||
INAINIES 20, aac set cacao Ae Seva achvtact dee velit anh Bet daa vautontutuctdentuetomtativedeevaicteatetect ows 1-2
|
||
|
||
Method function prototypes ...........cccccccccesssceeceseeceeeeeneeeceeeaeeeceeeeeceseaeeeceenaeeeeeeneeeeeeeas 1-2
|
||
|
||
PRE G:SyMDol is, osc fg l Secs vant te soges Wipeest bt codes sah eiet es odebseep sant hls cesteck Pui eedabeeramae 1-3
|
||
|
||
LON 8: Parameters so.t5 esse eestesistestediadestedia des tetiadesbtaads vemr hehe tiphaaaeliohatiehee 1-3
|
||
|
||
Class (las rarniss ses.3 02 c.cs(toeesthet sanvaes cas thet aceesiid ca thbeterevated oes thetoms iiatows eieheaevstnon aes 1-3
|
||
|
||
Class hierarchy,.2:s.2i0iinsGiien tien cei Ca aktoiee vein cei ia eres 1-3
|
||
StructtiredJRrror RECOVELY ..: ccs ccnccregescooepsssicongessbeaupsseteens oduteavpnsbcadsueds bed psdetadessdebspevecesesey 1-4
|
||
|
||
Use of the p_leave mechanism. ..........e ec eeseesseccsseeeesseecsseecseeecesseecsseecsneeseseeeesaeeesaeers 1-4
|
||
|
||
Pane NUMBers..e6s ese Stee nt cag eteal Cok etecahectathaabss sche abhadhubk dah aes sO dana hamaseel aa lau etuae es 1-5
|
||
|
||
2 THE ROOT: Classsiccsscccsctssasessasencooseseesessusacsasssocesosssbsccoessasosoevedscsoasossesouvesssconsadcesasbadescussewassessess 2-1
|
||
Class: Geta ti oni yse si5ecenk6 soaps scaceseeibecastevens dekes sncace coungaaaeuaneceewergcenesencconeneseceaseacesnese 2-1
|
||
|
||
PLOperty *iisessis Asap eicovie basdiiedeh cent hardier daheh badisodartid Avvdis datas Ausiiaieeniat aeons 2-1
|
||
|
||
ROOT Cth ods acpi: soss7s eas obs shes eat adh coe acens eupiti ed Soa ciien cea dicod dua Ties Seat of ota Ueeh sea te obs dha leee Saas 2-2
|
||
|
||
Destroy: the:tistan ce 3, s3iissaccsiesaniaiiseeteaesscatlaisacelescaacanesiecealesnah atiseutaatidertaniaseusectegsed 2-2
|
||
|
||
3 The TIME Cass............scssssssssssssesscsssessscssscsssesssessscsssessscsssesssesssesssessscsssesssesssesssesssessscsssessoess 3-1
|
||
PEECUTSOIS ieeet ciyecan cts fovea snneedanetedeuagannpacensvedotngouteccetetedeinboutsceetevedataceussceenetedadscusenesseens 3-2
|
||
|
||
Class definition .siccccccacecciecoean aeeisatecoedsas (devise te cavices cdavicencdevicae CUevicadieevacae cde vaceadenseces ees 3-2
|
||
|
||
PLOPOrey, oi oe: Sock in ut Ses Gloss teenken ses abet ccuvaurt Soe alot oan tienes alsvestitratens Giateasther den bivbeaetece ote 3-3
|
||
|
||
TIME Methods csssisscccssccanccsestanccsecvarcesersas ceseswancenvavancens seancenvacaucebscetndesvacseceasccdedeeecanccaaceae 3-3
|
||
|
||
DOL TIIME ay. forced fi leaec sc oeasaadu cede edhe odesets locos etic cceas et ce vheniata sd ovaabeuverinvedserionedtesdcavedvaeevedade 3-3
|
||
|
||
SONSE (UME sevice scsicdestedeiese deeds cedsgiuadcdaeduadedevisabecondsetedevisatcdesdendedeydenbedevccnacdbvvigandevvics 3-4
|
||
|
||
Add S@CONDS >. 22 ce. ioete cs caeh eee tite dh va sd ae Ate oe dad eee NOs e, aesla es naledonsdacstonnaebeds destiale 3-4
|
||
|
||
Add: days wicdetsii vid i eiiaedl ea ie ee vee ee a RE 3-5
|
||
|
||
Ad TOMES ios datedeeete Selec cate leas take Leia cata dena de Soceva dake ctaotes ebivdcavadupede (ecieecetolanedehedey catates 3-5
|
||
|
||
Ad YEatSs cs.250teoyrive gees tegieee a dayhiduseshees haber oe vQighe ben eae aben ahaa 3-5
|
||
SENSETOPMALH seoess cen LEM eet cceses he Neaeeteen oc ROM acerbec de Gack steetenk a Manian ses Guien ent deck 3-6
|
||
|
||
Set fOrMat. c:.seececdiveeecsgaceacceaa cease vesscccgeseanceaescet cegetsarceavscar ces duancenvicae cons cetneesvecde cdaveuts 3-6
|
||
|
||
Get system date and time information............ eee eeseeesseeceseeeesseeesseecsseecsseecsseeesseeeesaes 3-7
|
||
|
||
4 The SGBUF Segmented Buffer Class ................ccsssccsssssscsscssccsscsccssscscscsssssessssssesssssssesssecsees 4-1
|
||
PHECUESOLS§. « cceci05 feo2 268 Foss Bec Ais Bek cous Fa bee BeBe ok Bek PEP Me cov Hove tele derevd Feuadeit Pe desovt Paadeeete 4-1
|
||
|
||
Class etitittion, ic vceseceiters hc catesi toads eteatealesertoateccameauaeasaatecerteateqersaatageusaateoersaateases 4-2
|
||
|
||
BIOPerty sc. ssh s5 chk Secs Soetes ohccah cies dies co chansne desnugcochaneucausbuacconenehodwuguns cagneceneuevieeacaaenseoeg’ 4-2
|
||
|
||
SGBUEF methods sec) cicecscestiecsdessciesovsthdessesuseastvst idasduantdasoveticunesctdeassusaddaescesseasseenbinscreacias 4-2
|
||
|
||
DG StL OY: 205 ies cues cas teibe sel stuns cedeeves dul scunscuvtcuve iva stukeseTsavbes inh steve suv tcuvadas stees eUbsvessebaceve cede aus 4-2
|
||
|
||
WMI ALISES sxts.terssictec sts Aes tee tec cen ts Agectec certs ee cstds aces tens tes tactsa Bde tds tac sa Ande tiniaeie 42
|
||
|
||
Sense data by position ...........cececccceessscecessceeeeesnceeeeseeeeceesneeesseneeeeeseeeeeeseaeeeeeeneeeeeeeas 4-3
|
||
|
||
|
||
INSEL tet t taht thea dnctata coi decd td host ected hh tated bale Booed Shin 4-3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
ii
|
||
|
||
|
||
Delete iaics cevstensPevsarhsrets tues fevsanasdesstensdeyscedes cadens suv stevs duacdeve deasdevareadevsivensveasevedvosusscvesd 4-3
|
||
EXtract: fcsssssccscadseieessasisss adeeseseasshaceandeasooatesiecsotdaaseastetiasevagsaseestegeaes sbdsaseeete shassendaessens 4-4
|
||
COMPLESS eoiss ci iesssceeoeisacacoeds cvdgoss Seeauockccgdensd ce gesochdesdeschcashgustegvouubes goavete dedgauh Seesseebsgetaus 4-4
|
||
Count Characters ...t..i50.5..sses Aaidasts asses dasstest asses idsseh stewsees Hetsssdavdiee savieseaaedisaceteds 4-4
|
||
Sense previous Characters: ,2..5sc2sisects<k.aseeedhoeccts Savasubediaes aches aciwssts Aysievbstiwssda sees 4-4
|
||
Allocate:Se SM ents s:..) savcscstecttishicesvasuetcaieataneatacnsesnd slsseateauedesraaeageabascsseuessngeateaeoaaaaay 4-4
|
||
5 Variable Array Classes.............sscccsssssscsssssscsscsseccsscscesssscsesssssssesssscssesssscscesssssesssscssssssscsesssesoes 5-1
|
||
PRECUTSONS 45 fo fee.t cts testete genet oct beet stage aucouspnsnsedegets ceanpasneede fous ceavptutedegetutsausasutsdefesnasrevede 5-1
|
||
Class. didetatns:.22cvscaieneavin gyi nara igh eee ely beset alae: 5-1
|
||
NSA PE SUMAIMATY cs soctics co S62, octet set a eh ones sun svt fnbdu ony sunt cae lol ducaevSuunees ostdustnatses dates sasbeeesd 5-2
|
||
Record pointers s:icss2avgiiteieuiviat hn ieineveaia tens Savigeinieni eave sei ab aa eates 5-2
|
||
VAR OO Toe iisston fotetstecndn atts ited tort aca detlee atin, ck deren DN adstlts ca atte, adteawe os eat dep stay Fes 5-3
|
||
Class definition 35.3 s.yosecg.sdeshndesteeieiiet cies bes deeipiaes dibs be dasylesb dig ded yen dain dey 5-3
|
||
PHOPOCEY, 5b os iv Ses svct one biav oct cb eet ove ebGute ch Vouk onesie teae count caso Mute ae SaaWleavelibtess cnunt see onions vaca 5-4
|
||
VAROOT ‘methods: :ccs2ishehel nein eri eek Bel av RL tea Behl ee avd as 5-4
|
||
DDE STLOY :Ferssactis Sects tty erate dig eet oye catere pete corey ssstovepsteberephistesu peta te deynsstedvesSatedivadatersesdasedeveds 5-4
|
||
Count: records .sisc.ntyegiiiie avin Slee enyhitisr eel inen aisha anes 5-4
|
||
Append’ PECOLG: yeetes se snort Sak cal ostr tae cet GU cae aunt eet att antes Son ab eave at aM eeevtte 5-4
|
||
Insert:a TéCOrd 3.23.8 oss se giitei eu tei ei eavesivt ates Savin inte eavai iain mania 5-4
|
||
Delete a record ct ssecat on adseteyeent fp atagave pat tedover great iter ote eh paiat ie rot aaee Oates ae 5-5
|
||
Set key for comparisons) .:05:2205,5:100.)00s3 desde ai aaeb idee ee edeyie eee Derderian 5-5
|
||
Compare two records by POinter ...........eeseeeeseeecesseeesseecsseecesaeeesaeecsaeecseeesseeeesaeeesaeers 5-5
|
||
Compare two records by NUMDET ...........eeceeseecesseeesneecsseecseeceseeeesaeecsaeersaeeseteeeenaeeees 5-5
|
||
DOLE slesspsantiveyoaseentyDaeteaeeoduteens subse psdas sdesvaeh sveysdeg sav auubeveyodegsate buebeunvedebsunpreebsvtue ded oueyeds 5-6
|
||
Find (binary chop) css. aiss cients Gopi eevee deyheitesieestighbeni et Qipkineni a audhin 5-6
|
||
INSELEIM SEQUENCE. 385 2 sis Arte Sa Alois et ot astern ee Rho cat veld Soh ab oan ees Ghee 5-6
|
||
DCALCH Roksan ei Hes eee seats ea vii au ai eave vca saves uaaetausaar area eeuae ares 5-6
|
||
ROSCb is feces tails esti cep eeat stg cates ch gees Steg eane ave poeateteg slate de gaunuetyy suesace peiathae palttadegriet eégeseheveraes 5-7
|
||
Replacea record 2:.2-scsaHecatpdned causes begtpassd eas eed paid ees ego Belgie elevates 5-7
|
||
Deferred VAROOT methods 000.0... eee eeseceseecsseeceseceesseecsseecseecsseeeesaeecsaeecsaeecssaeeesatessaeers 5-7
|
||
Copy: Fecord ai.ssessctivad ee aii eee al ce el a ee a a 5-7
|
||
Get PECOrG LET StH ose, cesta slr scete capstan ty asut eteeetet slip bastedepeteductys te deetet alvh sete ined bottatoy 5-7
|
||
Swap two: records: .:...s:.saiyictesytest eevee agieoes aiyeeibeshedeel Gishaddeaydel Gitaayh ens 5-7
|
||
Tin 1a Sc Pot Se fe cee Sach Set Seek aan bie owe cba bet conn ete hat eos Baton tat oa catenins 5-8
|
||
Seticapacity via eei asi savas eis mathe) Aaseaaeeesl Ai eigain Saver guc daeraielae 5-8
|
||
COMPTESS 0. aveeaiter, ses Dever deegeset me pole lee paiutete psWiedapsenced yp slaules paietete pelttadepaaet ete grdessveveds 5-8
|
||
Delete:sequence of records: 31.2 ce.ssec3egeystes ainda bed piaid odes bes edepdans odes belddepiasbedes euldeyebes 5-8
|
||
Insert sequence of: TECOrdS 50.500 ee sttedk eet ee te eh ol oee eh aed ems te ot eel eteeahs 5-8
|
||
Point tortecotds:, sighs vat tiikwhdl sai. a ae ee 5-9
|
||
Point:to-PECOtd ata, «ssc sae set cous ante estevesc Soest bsbtedhpedeseeee bint echcevopouey bashowbeevenbeesndas hy 5-9
|
||
WABLX oe coche es ivberee ieee ain dase abe deloeeayhi seeds shai dusoyartbebighesdesopondd phe easyaibghiphesegsvienbeleyaene ds 5-9
|
||
Class: de tirinti Oia cicties se eect See dase eet see Lebeau fon doers ig aes ab oaes nat eee dhctenes tes 5-10
|
||
Property eisiseiSiitete caves cash ist leaves ease eeatdis ees ae eave ees Oe asees Se 5-10
|
||
WABEX tiie ods ise) zac coco deco tts sicedee sing oton ctetetet ete olteavecedet bee, edonaedbeathts alana eeatide, otaevep ees 5-10
|
||
Replacé arecord 3s.t s.yerigsategned ceiesbegipassd aac es ede plait eter ede dand ieee es eels 5-10
|
||
COpy A. TECOrd |i. ia eset Bese cae oh fetenk aed ee diet aattneal one Siedsoh eden taste tant ae steteree ats 5-10
|
||
Get record len sthissssssvhil eed ei eh a 5-10
|
||
SWAP tWO-TECOEGS: x25: esesctsleyssntecupete dosuyesnh ote stot odeybdetae vey etatedevsceterts edatedevbeobactpetstenteeds 5-10
|
||
WASTR vateeste es iitens ieee civdssnegisaeliesaydies aie heiessvore Gigi avn ashes Giehileynn eran 5-11
|
||
Class:definatiom '. esse, s. Sicetecn sens tittnast yestote teat test cantons Uist cen chitonts tet centers tes 5-12
|
||
PLOPCLly, 2s sitar aileasese aiaileatta wai aieaiasvist aint tui as oanbae ah auieateere aie 5-12
|
||
WAS TR: methods :sj ois: Sereda sates iececetlate patos ie de beep ate ai geest tO alate aise btes adh eat Stave ees 5-12
|
||
Initialisé.;cci..c3 tsa ial eee aipieel Gases ant aipinel Gaebeipi ines 5-12
|
||
Set Capacity ssi Anan ews ed ce steh Ad ett ated hut eet died kt hd Dead elk, at oe 5-13
|
||
COMPLESS Festi iekviNi shoes ert chs a a CN ins EGR se ade hy 5-13
|
||
Delete a sequence Of records ...........eeeeseceesseeesseecsseecsscecesaeecsaeecseecsneecesaeeesaeesseesseaes 5-13
|
||
Insert’a sequence Of TECOrds 3.5. s..550. alps cssasiesess Seay hes beeovees Gigdes ieeovoeee igh lecoviewsigyeenees 5-13
|
||
Gret TeCord Ler StH vs. sic2 sie Sc ces bat sak valet ets tbiee Sak alt cakes dee elds eek et seh eal oak auet Sus alt aahcies 5-13
|
||
Point toPeCOrd ss seteieavasiintaiteinn vier an raiser dials aia leniaraiele 5-13
|
||
Poti tstoPecord ata iss fy <dscceersces ener ed etes or dadses wi deest ea pscensst peter ee veden ste yeebeassotepeetp tates 5-14
|
||
Copy aitécord 2..:cscisctitaniitaineh mia auienielAl a epi n aia marae 5-14
|
||
|
||
|
||
CONTENTS
|
||
|
||
|
||
MAGA TT 20 cc 25s tus sachs duos 2ivsins s2ube covets beiiasavis PaybBebsda savbe palate bsdeudtues fusadeustonstubeseisduvsteySeevesenndet 5-14
|
||
Glass defiriitionss::c:ic)nistocsaacuths teense aosndaetieass eda oronlacntonasoudaken tia 5-14
|
||
PLOPELLY’ oi esses Bases secteeeh cpdeaes Sepbanshscsbeuubocsbovsbeasbovun de ybauste cevauchoeyscouhecesuacs Seetaecbeseventheess 5-15
|
||
|
||
VAPLAT methods = i.5:5.t.cuns cist Ae ahstenh eA inedoheohe dha sats 5-15
|
||
Tn tal Se vice ssc. beget ossets Bue pats tessseds dave ravatvosbods Biv apabade stots deseeuieteystobs Reesvbsdevseebadvassvietuvess 5-15
|
||
DEL CAPACIEY cesi.css sic hasondassesndceis seat aeciaigasd aeanganciasea is sestaaeneaataaaeshesasgastenuaceabassoasteasy 5-15
|
||
COMPLESS sock echacciss ioskouhs coafecs bisibasd cdebdocicdes deckadesduutedsedusdodsoivubedesduud ocesdcbedethorsafeveusseees 5-15
|
||
Delete sequence of Tecords a soiescssetiess sseispsaeiess Avisos aphisl vsviiaeserdiss Anoiissnarbosh aebabe 5-15
|
||
Insert Sequencé:Of TECOLAS: 522.5505 cocks fois Sooke, SQvue Pai bcheeceh stuks eubnebsden stabs suotebusten sunbeaete Pek 5-15
|
||
POinNt tO TECOL sesst iatscesdstaccctestacesadaiosenag anesadaiapsasagiaosntaiseeatan aouskeateeeban osendausceanea tol 5-16
|
||
Point to record datacs icc) sscilstei seieta es Neko ad bh a ebanehi adda elon adedeecrolorshisdedecetend 5-16
|
||
|
||
VASEG. ch. A woh isn a nkeanns uhone isl lanediilohs Moniicieiahs. 5-16
|
||
Class: defimiti oni ss os3. sits avscsisssehs ted eshadeeseets shveratateosteds doses cdetegstedsciseevds eveevbadiasevistavess 5-17
|
||
PLOPOLLY: eis sszssesccatacuenesadascvatastssospacaseastatadpospasasgasaazasseybasarsantadadeahegeaseniasis ovate huageshagass 5-17
|
||
|
||
VASEG amethodss:isitii tii etlisscei ened fuselage eee ck a Se dd SE a 5-17
|
||
Uniti alisesssco.scAseest tations: Aecsneseehisi dA secens Abnaies A aodeee setdons Anodesicasedoss Asehaabonegon Avedeaices 5-17
|
||
SEt CAPACIEY 5 s zee eos) ees dea Saphs Beal 2uss Lea Pengesue Seve fes Paves sud Fave ienaeens dep dube Seesceys and eabn coveceyssen dt 5-17
|
||
COMPLESSss:.ivicess shes isaceusteatethstousdaahbestestasevedaaigotetiasesedaateostesiaedeelsibeetaslasved ndsestesisy 5-17
|
||
Delete-a Sequence Of TecOrdS iif hein haddacalsiadiacd ciedaacileie nae 5-17
|
||
Inisert:a: Sequence: of TeCords s5..t).c:08 Asinisie pie Mas hae Mi Awe ee 5-18
|
||
PotnittO ECOL 35 oss sesters seks eebsth oss da Ae Seis tess Saath ts awesna Aan eeig eres Gin enue Aan tae 5-18
|
||
Point to record datass:.:isiscetasescessg id tic tapsatasices dda tspvatdaiscos dia izsateaacasdiategsaneagastiahaoess 5-18
|
||
|
||
NAXVAR b05 5.3 osc sbutia Sha Bosdoe sh abehidctaved saubiousolevaveb navbar lodevinn abt welowe aisles 5-18
|
||
Class definition iisoiss nctissiA sec sphasssesvtanhsvsedussdsacitse hathses vapsaboass bois AsotveedoapokeAssdvaseed 5-19
|
||
PLOPOLLY ais sceseees neds ceebeeh Stevesesbtivs des neetsseedeve ies eevee duvatevaceus side tubeeys Seuyseis stuvsdea aceysors ede’ 5-19
|
||
|
||
VAXVAR ‘methods: .s3seccustaviesaiagiacssetasa ventas iacendaaoeatag aoeetaerenteg assets teeslegiaeeestateosieaias 5-20
|
||
Tin tial se’ sci sess chess ces schba sidies se sbab hasta es me obabe dud eotors shstete eeheots eoestelbgkedeeeotsreheoeetacees cet 5-20
|
||
Compare two records by pointer .........eeeeeseeeseeceeseeeesseecsaeecsseeceseeeesaeecsaeerseeseneeeesaes 5-20
|
||
Deleté:a:sequence Of records 520550: As csistiessida stab csiethossuendhne cavSteessues dead eebadhoveuesdbiereiadhs 5-20
|
||
Insert: d:Sequence:OF TECOLS 5 .sescessesiiceaiisuspesnesuiteansesag eau sietentadaubensaaisteniadenpeasaanoasicees’ 5-20
|
||
Replace records; ...5.4 sats ice eeieet ahs latee dda beet eas eed heh eed ak 5-21
|
||
Copy a@ecord ssi sist satiee soisiaatiest Asetesp echoed A aitere Matis Aaoteas bation Anoieasaeties Antiass 5-21
|
||
Get récord: lem ethic: 2.528 ccsy.ccgseies pbseces covsceenset avks cas eebeaeh savas eavsedesdeh sinks restexesebstehereeiees 5-21
|
||
Point ‘td record datas: :.cisissectsstecesad testes lassetda teenies tassatdasoastgaiarestladcasteniateudateateaisaess 5-21
|
||
|
||
VAXEVARS 8355 cschh Selsey Sach uahl beech 2s ok eed Sa tecoubocoubved | dubeeui Seobuveds avhensh oewsabehs dekueut cevseehe gohesuh ees 5-21
|
||
Class definition’: cic. Bat Laie Monahan Acnslad Mihsthoe Mini oie Meets 5-22
|
||
PLOPOLLY fos cdes 30s Peis tens sc5 sched seta tens sedh caus feusdavs eth cebs eeMnteosrete Sees feiateoseets Mune eteesscsbtevaeeedet 5-22
|
||
|
||
VAXVARS methods - see VAXVAR methods ..0.....ceeeeeeeesseeeeneeeseecseeseseecesaeeesaeeesaeers 5-22
|
||
|
||
6 Editable Document ..............scssssssssrsssrsserssersserssessesssessesssesssesssesssesssesseeesssesessssesssessssesenseees 6-1
|
||
DoOCuimMent: CONLENE: doses cides asia hedess debs dedecebeause cabs tevetedsdescdats Gocedeterupedeheaedeteborupsdesstiy 6-1
|
||
Addressable character positions ............::ccessccssssessseecsseecsseeesseeeesseecsaeecseeseseeeesaeeesaeers 6-1
|
||
USAC eee ses Sit ceetits es sath oenvalts Seu valet onus ates cee velntoaes tenses adams trstems abate utietste act ots teveortt 6-1
|
||
PECULSOLS His cathe eves estas caveats seaval mates mat ea tare aat aseaueieeaTaasea: 6-2
|
||
Class di aorariis ial siyadecdee fetat te vatogtiigesat te votes i peasthtevoteasigaiat uvedeuseg har etat eps tadewsp ees 6-2
|
||
|
||
EPROOT 5:55 scscerieechbecisbesbetes Tab Soe Dati Tas eased das ewe bea aed ee zaps em epee 6-2
|
||
Class-definition cx 6..i00t.2. mail tet ele Aue et at Alt an eat ett 6-3
|
||
PLOPCLLY She ests avd ait eR etd Ae hd pe eed te a eats es 6-3
|
||
|
||
BPROO DT neth Od is. 2c3) scccesut ties cstecnyesa pede busters ade betes Seeterndaded sing beetcaudede seit besten dedehedtsPexteeed 6-3
|
||
Del CONTENE acc ceivsesbdephuee at eiph Hedin eiyhel ie sedee Qiyheh nL aee Aves besirana dain oe atest 6-3
|
||
SCAN; DY WOT Jeter fa eheteceehas A above ct al Sb tek tina ab ecivuat at abuteeahine At ai edivtantonet 6-4
|
||
Count Words: s.fealnavgiste eueviiia tenis velit oavai iin mane aame reins 6-4
|
||
Sai by Paragraph oi cesses Pies ite cedeseeedeses sie evens ce dodetledh p esate edozes poe vonnede Poses yohesdetnveeadeesaee 6-4
|
||
Count paragraphs <ts.aietudestnttadsteneied aera aay betaibha tied 6-4
|
||
SCans DY DIOCK:sycscecee teats aed cael tet Vavcd ages adetack Gavel oath snus acbVerct athe eihtech oust sana neetesbvanstsen’ 6-4
|
||
Append:a paragraph .:incieteicaiiensaiiie viii ae avalos avalos Aieasese ieee 6-5
|
||
Copy whitespace indentation ............eeseeseeceeseessseecsseecsseeceseeeesaeecsaeesseeseseeeesaeessaeers 6-5
|
||
Copy range to front of clipboard... eee eeeeeeeeneeeeseecsneecsceceseeeesaeecsaeesseeecesaeessaeers 6-5
|
||
Copy range to back of clipboard 0.0... eee eeeeseeceseeceseeeesseessacecsscecsseecesaeeesaeessaeesseeeses 6-5
|
||
Insert from, clipboard..:::. ss. sshstetssatees nevis sienteei cesveeissasi ote main oatauanaesiaintes 6-6
|
||
Modify characters in a range ......... ee eesecssecssceeceseecsseecsseecesseeesseecseesseeseseeeesateesaeers 6-6
|
||
Copy: text to: buffer... 32.538) gieeiteni pitt bhecisdeite mies gig eite hs Aaya Rae 6-6
|
||
Set document Capacity s. ..: vs: cout segechvstas Sev, seitonk satte seehasbevbect sna bieteeeshavesteabtbeveetetesstebaus 6-6
|
||
|
||
|
||
iii
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Deferred EPROOT methods ..............:ssccccccccesssssvvescccccecesssvcsccccceeenssevsecesceeeesssvsscessceenessees 6-6
|
||
Tritt lise sss. ct42 toads herent ths aise en kect et istac ints es sisthc ne hsdc te iatie ek de a dtatic 25 Sour Be ioc 6-6
|
||
Sense document len sth ss: sic. ocilends shout eelonedl shui vslereh iach Helonbserhbadd beleibecdeaks 6-6
|
||
Sense Characters forwards. .........cccccccccccscsssseeeccccccccesssseccccsssceuseeeccccsseuecesecssseeueeseeseess 6-6
|
||
Sense characters backwards..............ccccssssssccscccssccssssccccccsscesssscccsccssseessescsescsseeessesesees 6-6
|
||
TM SETE CH ALACTCES 2e25.c5205.25.ctcesiaees Aces taskcees ga AGosRGaSea saad AG a REGE NA aeRTED OSE ReE Aca e Ie O 6-6
|
||
Copy Out Characters s..5:.c5065 cestineisduadoctecghtisvedeaiess odeslosvoleubevbadesdurbedes dvaseoredbavocseboduagectoe 6-6
|
||
Delete Character ...........cccccccccssecccceseccccueecccceseccccusecsscuseccssueeceseueecessusesessueesseeueesseeneees 6-6
|
||
Clear the: document: 2s2085 205 ccs reoiacec tea leassrededcvedea less dledehedes daegeseDeeehe deubgeuesebedevedes Seved 6-6
|
||
Compress: allocated storagersis.c:sccibsssccescecaoeeadausce biccacsondauseeeieaeaosundaseastgaiasonnbanieasteas 6-6
|
||
|
||
IES EAN Mies ore ac ort es eee ee eae eta eae ct Sta, eee Se tae aoe wach. out aie Meet ce Oe cul teat ache tee ail leg 6-7
|
||
Class definition ............cccccccccccccccsceeesseecccccscceessseecccsssseussesecesssseueeseeesecsssseeneeeesccssueees 6-7
|
||
PLOPCRLY 3 ozs ccssceus cuvteeds tess ds hessvbtines cous eve evbsaues cessakbs peuseres sevsdee pevathossevs dues edtevesces covets 6-7
|
||
|
||
EPBLAE methods osc22c% teestsres ices tecteetiate ates ie teeter ts ate Sela Tr te lie ee Solar teas Sole? 6-8
|
||
DEStHOy sso scib esi ied csbccetsdubdosh Sisnceuis ietdovbasuhdivbedu Govbeduhdivsudea Seetacceivetedeadesteduaieuheloatevscdgeene 6-8
|
||
Initialise tsk ated Se Att eta el tae Se teed aes tah teal A eed et ee tad end ks 6-8
|
||
Sense document lem eth sos. 8.1553 2655 fev Ssens sue devs cov ssnss sues dove Sos aceus send Puvetueitebeauasedebstvbsces ss 6-8
|
||
Sense Characters forwards. ...........cccccccccsssssssscccccccsccsssssececccssseesssecceccsssescssessseeensesseees 6-8
|
||
Sense characters backwards.............cccccssssesecccccsccesseeccccssceesseeccessseceesseecccssseeuseeesseess 6-8
|
||
Tnisert:chiaracters:..2332:3.cc And Ravana whilain tania Adana 6-8
|
||
Copy out Characters i.isiecccis sass cossehas ceva chan cevachessevs cha ssvva uss sea ceussvucdavssedessevsdvecseds iueedss 6-9
|
||
Delete: Ch aracters:45 32225. scsic a6 tes Ssnecte sia soet a Sieeste datos reasea ested aos teatearatessebaneauieeeteasearnets 6-9
|
||
Clear the Cocument ................ssssscccccscessssvsscccccesenssevsceccceeensssvsscccccenesssvssvesseneesnceessees 6-9
|
||
Compress: allocated stordger..ssesiscshsscAdssiesispive.desvienesuss dass svactibe vardiesseanivsssusrderensse ds 6-9
|
||
Set document Capacity: coset seis cosh zeus devssusy sve cuvetevssusesvesduvistoussipncvhs fetsteyesntssubesebsteesee ss 6-9
|
||
Set buffer sranularity: . .:isscs.sesiasesi lates .teslascatlesess beatae at loasoastea sce aadosoestesioceasiaadeeetats 6-9
|
||
SOMSe Star Ol CAL sce: soi vecjic cea shes duck oe chews sanscees Goebow eho cecves dewhuwina cpanebedsdeeeiee bane oveneenee 6-9
|
||
|
||
RSE Getter Al ad ese Lek nd A A Ste Deed btn dee ed oon ta deed be sie dee kOe kke oe 6-10
|
||
ce) FeNoSoira 00 1 6) 0 UR re a tr So PP eS 6-10
|
||
PLOPELtY.. fessaccssesisccahssysa cand sikteetases testes lecaehausdcasasast sabagesceusa nase duaacasdestasaseeatates toute cant aed 6-10
|
||
|
||
EPSEG methods.............:ssccccccccessssssvscvccceeensusvccccsccesesssnsscvccsseenssescvseceseessvsssseeseeeesuvesceens 6-10
|
||
Wniitialise teh 8 Se Atk oa ed te he as ad ae td ha eh had lahat ee Shea CA 6-10
|
||
Sense document length ...............cseseesesesseseesoeeeenscnsvectencnessonevssesensstenseessoneesenseneneeess 6-11
|
||
Sense Characters forwards. ...........cccccccccsssssssseccccccsscessseccecccsscessseeccsccsssescessssseeesescsees 6-11
|
||
Sense characters backwards.............cccccsssssescccccsccessseeccccssecevseeccesssseeessesccessseueeeeesesess 6-11
|
||
Trisert: Character ss... 50s c0035cccbei3 foca beads ooubs Fi desabecd dviads fe dsaadacliviese advanovidevie ds Adssabsstestedi hess 6-11
|
||
Copy out Characters s.isiecscsssasg ceiseuessethaiag retadioosets cia ssvateuss Uackussvadavssedeosevsduecseds duecdedse 6-11
|
||
Delete: Characters:45 032225. scsucae tes Ssnestas acaetiasie ceheassGoenea see satan snGastcasea sates at ataG sheeted areas 6-11
|
||
Clear: the :dOCumentt ui secseccc loess eli zeve ces Sea ia i tiecttes La eaten nl ode yesehe Den tees ode beset edesdueooaedeee 6-11
|
||
Compress:allocated ‘storages. csescsesiss dasdekesesghias teandadeoesedib ace scdde nsroeeedeassabsonanbsiensees 6-11
|
||
|
||
DT, RESOURCE HINES 5.5, 6.4 scacseacaataccetetecescdesctaccdsseccinsnsevadssstecssnneseoessdetenanzescecdsdeteassctesesescunsncdotecsunenons 7-1
|
||
PRECULSODS 2.95 <fetis tees Oe cakes AG coe va cee eS eaee ate case a Beste cae OAS cae ect cae ee 7-1
|
||
Class. definition iss. 2222ecses Mase ee ng a ee de UE ee Es ade 7-1
|
||
PEOPELY: sees oes 2c utcdevedon stu sactecavgeeet suurodsveveusast att oath congouusstugonch voce suatstheedsteweeseubetsyeaeeaecvets 7-2
|
||
|
||
RS CELE: Meth OdSissi.cesc3ec3 eset es oa a ee Ve A 7-2
|
||
DESY: c6soseet eek A A RBA BRE AA BNR A AN aS 7-2
|
||
Initial SO isiosee iat sehi les et eh Rese ve eR ee Ee SS 7-2
|
||
Allocate buffer and read reSOULCe ..........ccccccccccceseeeeeccccccceeessseeccccsseeessececesssseeueneeseess 7-2
|
||
Read PeSOUT CE ai zictcaccti eee eich Recbes Basa v du pe Be eee Bi See ewe E a eae waa b sven a Oa who de aussie 7-2
|
||
|
||
8 Binary File Management ................scccsssccsssscssscssseccsssesssssscsssscsssecsssssssssssnsscsssscsssecssssssssssosses 8-1
|
||
PEECULSOLS Ss 2 este tiette tts Moo ter tase ncstistic eset ss it cs tsthn ast aticeurte tn aches ects he ce 8-1
|
||
Class diastatii 2.5 issih iievneleadtheda late adult skid ei teeta ncesbe reseed 8-1
|
||
|
||
IBE TCR etitsst dct ta atta ata acted ts am ited De ied acted esd ited eld Mise Weed ble 8-2
|
||
Class:de tintin: 2.3 208:22 ossede doer o55 okt eve Have teco Races oPePhS coe cole Sune Debate Sec eDe luvs feNeteceen de deve Bese 8-2
|
||
PLOPOreysssisuec sssdsacessdeuss saeasascistacesceasesaseuatatessasbesesoeshatanaosbatassasbedanaeate sasseotedwsasatasesons 8-2
|
||
|
||
BFILE methods ............cccccceeeseccccccccceeseccccccsseceseeecccsssscueseeescsssseueueeeccesssseeeeseescesssseeueeess 8-3
|
||
DeStr Oy. ssiss sons sestiaes de stoees svstbeni ha stass castes Aasecnasosst tanh sssthigs suet dass daetbaas ovetbess seatdess sues Sos oed 8-3
|
||
Open Nessie eseccs heel eager Heed aeee nse Al iegsect isl aaeceast Abdel aes ethan tekst 8-3
|
||
CLOSE files: cicdikedstesiaseedssedstaasaseancasods tad asetds Aes elas BOSSA AES 8-3
|
||
|
||
|
||
iv
|
||
|
||
|
||
CONTENTS
|
||
|
||
|
||
Rea fr Or Fil 6 2s fesees fogs 2es Pes ecacdeg stevs eesdihedatedevs tea dtcecdad stuvatesstebe ealsdevstenitees fa s3H 8-3
|
||
Set bullerSiZess:ictaticeeies tee codoncdetisasanteiehus ao iedatehtdsiaa eee is 8-3
|
||
SENSE TECOLG 'Aatais: cisicicisisssiicchisisieseociucedeseioscbesehessdoses oeuseehessdoseasisnesssesvieselored 8-4
|
||
REpoOsition to: Start...3.8scseiceetdeessbesde tebe ssiebeortedeviseesbiiseetedeioee bik ortedi one bits 8-4
|
||
SEE NPE. See saute Raaesb cere th ok ovds ahs bcebsts aoe lba dwbcug ste ose Da duehcenede Seo adiee beads oe aden ead Se stereos 8-4
|
||
CVasSsdebinitiOny sic2ccc2s2dssesstic ansscacesteaoastastiecatesteeskessatoates hoasteaseacstesaocsbenseeconessaeees 8-5
|
||
PLOPOrey ssi scckssceiesid Sesdeuk be csdock Sesudors sfetaerhs devanedoasecuhoassdueioaveacete dueceatorsSaeuboisabovsoietaesselss 8-5
|
||
TLVFILE methods .00.......cccceecceccccccccesssseccccscseeeessceccccssseeeesseccecssseuseseeecccsssseueeeessessssuuneness 8-6
|
||
Open: TV le vss cessecvses Sevscadseleeced taevscepteivoees Saves sedvsed aise server ieee dsatordsucsca ste 8-6
|
||
REpOSitiON 1O'StATE +. .sissscssssscsaseslassessteaesdeesdaasessteaasesesdaaseusdasessesdaaseveseaasovesdaasouetesasoaes 8-6
|
||
Count records ............:sssscecccccceessvvvsvccceeeessevsscccsseeessvvsscceccueesuvesssecceeesenvssceecensessvesssees 8-6
|
||
Wite a LECOI ...........cccccccccecssssvesccccceeensssvsesccccesensscescesccssensuesssceceeensssvescecessenesnseessees 8-6
|
||
Set CUTENE TECOE yore co eos ss obs teess Ra deshecdetenssebsduabeadeoss dadwodsnbedeossbadeeseeteduess Wedemseeeees 8-6
|
||
Sense current record NUMDEL ..............ccccceeeeeeeccccccceeeesecccccssseeuesseccecssseueeeeesecssseeeeeess 8-7
|
||
Delete a record ...........::ssscscecccsssssvvvscvccceceessevssccecceeessvsescececesensucvsescecseeessssescessceneesseces 8-7
|
||
ReplaCe:a:Tecord sss.c..stisstsesshessorevbins Anphiasceun ie Ae idessacations Ap tisss eis dnedsseasedewoaeedibe 8-7
|
||
Read record of specific type(S) ........:ceesceescecsseecsseeceseeeeseeecsaeecsceceseesssaeeesseessaeesseeeses 8-7
|
||
TL VIDA Avis teh itcitn .tstal dinette eRe cnc stac Rater nthe eRe Bade sa otee ha Belins Rictee Re Bede doc 8e 8-8
|
||
CV ASS CERI tl Onis 43 icf eekideiihe ci coebadudeccacenagvetodedeusa ceus Ses Seveceass vosielodenecuadseudeetedevesiensesseee 8-8
|
||
Property oi: Jnisi ethan Bhsi habs dashsitieiindaiida ibd hao Aan sedi Aains 8-8
|
||
TEV DA TAs ict 8 rscinc sesh ctscinccets fash eeetic oss Daan ate wie eadeecbereee use ie danse vies emseeees 8-9
|
||
Open and read Hess .sscssssvsssssssaseagsauasesusdsasiaasdvasesesdwabesnsovaaedwabestsdveseated vate sesdvaoesteo ees 8-9
|
||
Save: datator Tile ssc: i025. 25 si eke cet aces Seek Such nothoc eneeeh dew tgoul sees euicneues Souk cen cecbudettvedctesieebenev eee 8-9
|
||
Checkat changed s: 0: Jes. fattesicey ha Asthsisasiote Aatisbieue iets Astisusaoslasrdagiesinnsals Saphass 8-9
|
||
Process a record read from a file ........c cece ccc ccccceseeeeccccccceeeeseseccccssseeeeececccssseeeneeseeeess 8-10
|
||
Get a record to be SAVed.............sccccccccssesssvvscvccceeeesssvsesccceeensusesecesceeseeussssscssceeesnseessees 8-10
|
||
Reset allodatasscciso cc cc28b ssi coos cectenehsdcdeceacewasvetedededencs suevetedenadeasivecseledeveceasscieretedevedenssener’ 8-10
|
||
Deferred TLVDATA methods .0.........cccccccccccccesseeeeccccsecceessseccccssseeeeseesccsssseuuesesesesssseeneness 8-10
|
||
Set the TLV file characteristics..............ccccsssssssscccccecesssvscsvvscccccensesssescecccesscsenssnsessees 8-10
|
||
Set in-memory data for a record 0.0... eee eeseceseeceseeeeseeesseeecsaeeceeessseecssaeeesaeessaeessneeeees 8-10
|
||
Sense in-memory data for a reCOrd .........eceeseeeesceeseeeseecsseecseecsseeeesaeeesaeessaeessneeeses 8-10
|
||
SERBIMGE 7.24553, nts kvtsst ete sods eens Abe hehe aed aS ta eh hae Ok it ad ee fn tO 8-11
|
||
Class de tim tions gees 28 sees cts 2d bees ce ae snd eee cetleeesdDctenoeeleevedd Leeheeetlgesseed cebec eS vebede 8-11
|
||
PLOPOrey. wici.cissisessesiassondavissatesiassendavssectadasteshdsvaseetasistoesdsavendesisteandsvibeetasiateetdseeeataa tes 8-12
|
||
SERFILE methods ...........cccccceeccecccccccccsssseccccsscceusseccccssseeussesecccsssseeevseeccecssseeeeeseceesseeees 8-13
|
||
Reset all data.............scccccccsssssssvvscvcccecensssvcsccccceeessssescvcccseensusesescscceeesaesssvccsenensnveessees 8-13
|
||
Set the serial file Characteristics.............ccssccccsescsccccsscsssscccscccsscessesesececsscesssessesssseesees 8-13
|
||
Set in-memory data for a record 0... eeseeeseecsseeeeseeeeseecsaeecsneecseecesaeeesaeesseeseneeeees 8-13
|
||
Sense in-memory data for a reCOrd .........eceeseeceseeceseeeseecsseecseeeeseecesaeeesaeesseesseeees 8-14
|
||
DO The: CLEANUP: Class vsvsccecisccdecsasncsvecesessecsancssavcesestoccascessesssessecessssvesescsanccesessvesessaencccsessascaseeens 9-1
|
||
PLECUESOLS .f5.c3c5sesvedeaoige reset cubes dhe yaeeon da vbes td do veds Dasuvdae videptee va devduesdgevesnbd guvdoee ddevneenesvenees 9-1
|
||
Classdiaeram i250 28 attain oiled Mal eee al ae ea en 9-2
|
||
Class Cetin tl Onis oeicvescoses eels ves biecde oeseudtsdas vei ose aod dea Ee 9-2
|
||
PL OPCLUY: 4 Ben csgvsssatete daduss deaades se dedes svesacesevesodes sass sadtsde voles seuscuateassedepessveest seu vedebesepeeeteaue 9-2
|
||
CLEANUP Meth od siscvescsesccseseceirtet aise Garb Sev eo Renee aoedes en ee eed a eS 9-3
|
||
DOS OY. cose: eta ces teehee BO ee ae Oe este iat Ae eR hit sete OR aR 9-3
|
||
Mmitialise:liSt:o3 sss eee ee Sh eee a es a es 9-3
|
||
POAC sets Sect cdedetebaties sete A daebatcs camhe tedewicus eae heeds todedes oust dotonedic stabs todethetistaehadee 9-3
|
||
ReMOVG TCE Ti sso cceecst eshte tase ase ad castes ae ae bee Cea See se Sav eae 9-3
|
||
IDG leven teint se x Ae Bn ale A cl RM Ba RUM ah it Reh ah hin La Ble ad tot an tele 9-3
|
||
Delete all items at current level ...............c0sssccssecccceeessvescvcccceessssessvecccssensvcvscvcesenenssens 9-4
|
||
Bel cleanup EVEL 3. v/s rer ewacsetssvetes saa deces seus dees aude codetustuehectdevateae sbustecs dese oteepentovedeantene, 9-4
|
||
CLEANUP convenience fUnctions.............cccccceeeeecccccscceeseececccsseuseccccssseuseseeesecssseuenseeeeess 9-4
|
||
AGG an TtOIi hs se ttt ae clean ahaa oe can ht Sal A eh et ak 8 eh, ae Lak Jt eh, bn dak Zod Sk, nce PON 9-4
|
||
Add an object .cc8nickinaveinnciiiraive al aa eave ee ia 9-4
|
||
Adda: I/O. channel ie sce sisi cetctideses sdvcteeectedads dsdesevasievedesedestieusiedodesodtsaseostededasotusteescdes 9-5
|
||
Add'an allocated -Cellisii..ce 5 ivbcsac cesta eivk cbc Savas Bev ce kbs dav bu sv ev pecs ae doves avs n bev bewe ke 9-5
|
||
Add a:shared:allocated Cell ic. cies cccctuce ceseabetschedant ccucsvceccea tune cuvesieeccnsduveconesetectesdueeseeceee 9-5
|
||
AGG: a DYE xs hooey Ge Sect ast aleastiaaetsu aloe desde ee eet 9-5
|
||
REMOVE2AN AEM 06 ce acca eaelcertsoteysddgeteaecedateuevecsued ate cskeseasoeteseedstescasoteetedstesc ate svddedS 9-6
|
||
|B Y= Fei asee2) 0 ah | 08 Cee ete eae ew A at ee ow a a Pea a te oe a 9-6
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
10 The APPMAN Application Manager Cass...............sscsscssscssssssscsscssesssscscescsccscssssccsesssscsseeens 10-1
|
||
Active Object Pri Orities ss .syssec sees secgsces steceveseactaeca stucedvedechere sted edtpodsteteguaeteote eusteevpunet#s 10-2
|
||
Active object ‘scheduling s.::2sc.ccinsceineniiiipenide tine. ieee leona iaeaeainns 10-3
|
||
"Phe 'a0--T ON FEtUrM: VALUE ek. 8 8 ee see lB ee ete See hined sas GO ok Bek see RR eS co Rs 10-3
|
||
PLOCUISOFS asses sai iver eb ei Reeds eh A Beit I BU ee eee a eeieraeeNs 10-4
|
||
CLASS: aS Tami elo cst ce ate salee eek cidade tots beat <desetes ois restedesetes ates ientevevened tanbawiaretoetescetes 10-4
|
||
Class Cefimitin icc: cesscseceevecsendeveigens cavacnecens cdancesedandesscdaadesvadeadesucdeedeaus cosdeatadenssavceoess 10-4
|
||
PHOPCEUY. isos sek cote acretiics dur cies cane tuet see abn t ota siuk tavauteaiv syne cee (alwtedes Watses dautetietagt Se Gute a 10-5
|
||
|
||
APPMAN Methods o..d.cccssccseicaectesicaeceesccaaccesccaesesdenasenvecdadubudedaceaucdsaceundepasvatceseevancesseeateds 10-5
|
||
Tint altSO%. oan seevactess darecevedvaatevscaaazedenasasrvacantevsvedss oevvedsavisetesscicedesavigcnesededsee Meet A 10-5
|
||
Wait on I/O semaphores: ...:2:.:.505.2.cpiteditedinieed aevieibedivdah dines bespine eens detbdadeebece 10-6
|
||
Start Scheduler 08 ote cette Aad lee tliteexlaesdeaseitidece daesd ae dbo Gee ete Aa ieee 10-6
|
||
Stop: schedtilergssccnsict. vei igi ved iv Ri bia ee i hea are ee nee eee 10-9
|
||
Ad ataskes.2. occ stcscereciecvesediveceteredots Gets sentecedelstedevbcstecedetarelivrinteccuedstelevicntedededssedeerds 10-9
|
||
Load a: TeSOUrce isis ccessccdeeeeccidie vases cae shdbasaedisbesaeiaboesandesvedelieseedardeveuserdevvasrbeveusanbesvacs 10-9
|
||
Load a resource to a DUfP EL 2.2... eeeeecceeenececeseneeeceeceeeeseneeeceenaeeecseneeeesseneeeeeesneeees® 10-10
|
||
Generate resource file MAME ............ceceecceeeesceeeeseneeeeesceeeeneaeeeeeesaeeeeseneeeeseeneeeeesneeeees 10-10
|
||
Display TOtter: 2. sescset states getec scees deh gadat ppevedeuseh ga sec eaup odeseee paien sep edesbee grates ovat eee eeeet ss 10-10
|
||
Notify an-error:..si.t.cyiiecthaee teeth eee baesd (BRP a eGR ERE ER Raa a 10-11
|
||
Clean up resources and report AN CLTOF 0... eee ee eeeceeseeeesseecseeceeeceseecesaeeesseessaeesseeeens 10-11
|
||
Find application image file... eee eeeeeecesneeeeneeceseesneecsseeceseeeesaeecsaeesseesseeesneeeesaes 10-11
|
||
Ensure only One COpy FUNDING .0..... eee eeeeceseeceseeceseeeesseecsaeecsaceceeeessaesesaeessaeeseeeenee 10-12
|
||
Change active Object Priority ........ cece eececeseccesseecsneecsseecsseecesaeeesaeecsaeecseessseeeesaeessaeers 10-12
|
||
|
||
11 The ACTIVE Class and Active Objects ..............cssccssssssssssssssccsscsecssscesssscssesssccseessssesessseees 11-1
|
||
PLeCUTSOTSyésiscdstaticestdsasesttaiieesadataacatds ooensa aaes tea ioarsiateceatea oo tia eee ion lista atioaes 11-1
|
||
Cass Ae tamiti omnis sss. cish 255 eesensecn ccvnctel benadha ceusenst age ieneaceva diel onetateacectaneteaunedenseceetetsinnerehed 11-2
|
||
PLOPerty wisscicssseecne dic ocasdtetess Mapbasasete ds i Auanduad cated esdvsndasdshdeds Padvaaseedscdedi todvandestsetsiesbovs 11-2
|
||
|
||
AGTIVE methods:.5.3 cies cute zyore ha Seeneeh teu ece da sven cidade neces dead euvtdyeeec¥a sues ceUa dyads da See teedeauetecds tuned 11-3
|
||
Destroy the instatice .:-icsssgsisccaiieessiasdaceei caus candi icasigeaagesssaiossispeatas aoedeatseateneaonelass 11-3
|
||
Initialise the anstanice..i2.c5<cicsii.ceccgeckccchcecssietsneees oiuhelepodeedoeseactssvenshenevadenoeseetseederectes 11-3
|
||
Make -airequest toirutls: iscsi A sctisenstiss Aathstdnien Anriesi ann eeu einen ae 11-3
|
||
Cancel a request to Tun vs. itscssssesscavssed stays seitcavesdsaevessanecvsssdseves seitcvesstsswessusscevseeh steusee 11-3
|
||
Hanidlesan: errors: ic: .aisaccsatavicestaniaceenceieeasseniacantanieactasiacoutinion tasiaceutentoueted asunndansaees 11-4
|
||
PLOCESS! ath: SVEN EG ci ccs sous chek Seve ewes Saye coed lewd ewes sand outed Sevdewws sawe coed Seed ques Sawaawes Sevbeis Souhewenleebest 11-4
|
||
|
||
12 Idle Objects and the AIDLE Class ..............csssssscssssseccsscsccssscseecssccsesssscscesesscscesssssesssssssesess 12-1
|
||
|
||
We OBjOCtS s.ccsecicvecseeieveian aes tiated ec anndeeucdand eve danndes uedagdest cde dea uecdaedeatliaadsauidenesatidsebvabiaspasbiees 12-1
|
||
|
||
AIDLE), «.\ bectseeenctih ahiat eit aad see iota eee te Lo a hae ote bites 12-1
|
||
PRECUTSOLS:ecsleecese aids eer edteese ia bev iaseceau cos ae a veeb tea e eaee cea Teev eP NN ReeA eves sR NeeTegEeNeLS 12-2
|
||
CG laSS: dia SE aI ont fes oat echige eet ges Seat so date odes acct edad eet le beeke de peegeies cote teyedatvesntedesotereals nists 12-2
|
||
Class Cefimition i s.cccssisesceteiesavdeveedanicseesardevecderachvucandees stand evvedapbenscdaadesuedagdeaucdeveeatedeees 12-2
|
||
IPEOP ELEY. 6 ose ok ocs ante bet vee ck ett oaea tect seesaw tone Seve eu Cauat cake tacbnts oaliteces tevests Gaus otha teeketnaaheteess He 12-2
|
||
|
||
AIDLE meth ods ic: ccscicah cess cevsesancdecevas devedsa nce icaa cove dcnac du ccaacueudedeces vadda suaudedacsascdaadvandervestees 12-2
|
||
TVA SOs ose d od scites Seance vdestue cae evtenecedetats cog rebeceesdesetdeatas ecstatic cédaust seesedessMeetesscudetstecieeass st 12-2
|
||
RUM eee eaec es bees sa 5 a Be Read os ew aa ehh Ten gat eae bs Beda bee edo dea bedeb bg bea vaee anaes 12-2
|
||
|
||
Examples . 230i ein ia el Ae ae Ae an Aeon Ghee ates 12-3
|
||
|
||
13 Timer Active Object Classes.............cccssscccsscssscssssssecsscssecssscssecssccseessssssessssesesssscessssscssesssees 13-1
|
||
Class diasratn 2: 5.20585. Se Hn A SS ts SL SE eg 13-1
|
||
PLeCUrSOIrs isis thess A aodeasovstiess Aaasbiacconteess seandian oengeeessusvdseeseasguee svandeenceasbas dvandebacessbeaboud 13-1
|
||
|
||
"EIMER 3s 2203co 2:53 eeended segs ent cebaded Soeuscuee suescehsdexs custauvecasdunvs tush lvecehsdune covtsuneg ch fuvnedee thoes Sieneds 13-2
|
||
Class: CetnitiOn: sceissstacdteovstes aon sade ties chasis sala ade teaacenetahecstea age elaedancasecentase tess 13-2
|
||
PLOPOLly: 6 soaicch odes se cdeves Sa stgwesdechveuh ocbh cockscsteuus degdgostacsbevubecubausie aveumenca poauute esbaeuhoeeseerh oeevech 13-2
|
||
|
||
TIMER methods:....02. 84s uaada end ahaa asain aontacn aaa netted: 13-2
|
||
Tin tala Ss :2:. 5.0; tees seta degst.Ye Seosduda be wseeis Sees cebadeccseds deesdeg ade ustavaduusdusaguasseda duaduvetvecseds tueaeelsd 13-2
|
||
Olle (relative): s<.ce35:4 scores esas iets neezessacanncssk aoakesas oa uacash tebe ae UST EI Os TES AOD 13-2
|
||
|
||
|
||
CONTENTS
|
||
|
||
|
||
Queue: CabSOlute) ec. 200c es s2ces ve Bees Pee Pbces Peve es Pevadvhe PeVe dees Pevbbeue Peds Bes tevsdebe Celedees Povbbeeetevedec 13-3
|
||
ANIMATOR< j5:.cTiscsisvesnarssndaviceehaginnesadaisecanag aoecksshtaehan aoseudaieecatag apsekdasoasaenapeuadaseasteiiat 13-3
|
||
Glass: detamiti Omics, ccsenctt Seng8s ccstetsactecen ta veanctyant esuntant ciunoactesunde ceeretgneneseiseceswengeetesteadeoeiey 13-3
|
||
Property ui. cissi wih nhhinnes dabndnhsiinindaii dai eanhediakeie 13-4
|
||
ANIMATOR: methods 32.0555: Abs csistiessba tive coisteoss Ds shvs eateteosechs dvs subathoseods divesvateesichadioes envy 13-4
|
||
Initialise
|
||
Run........
|
||
BUZSND Aside ion sitet cid atis bathed issphbievi A siteas seebisl vsteas erases Anodiaiaetioe Mattias
|
||
Class definition
|
||
Property
|
||
BUZSND \meth Ods0eic5 ce; oi aeks Shel lace iath coehan u aed descoen Geeta cod auscees couscaeheavscceaemesnceneseacees 13-5
|
||
Tita SO: etess fess oilsdcads ls ovts teas ceceheabectedianeeceda casa te sua cevaedues cute ddatsavnnaes cubseeec eseauns suuatiaedes 13-5
|
||
CAM COs sos cies Seuseuittaws cave dexcenvachussevasunotigavevssevachwncepaduessdsacenasuydueveracsdusesuveduesevesdeverebeaey 13-6
|
||
OUCUS 2 ipcccsses cher te thre tistteetie ie dke coats e oat teettnadesterestaticrat tse raatecie rete ttereetstie cates 8 13-6
|
||
PRU pei she sot ied Soe Gaske Tou Goeh Pek aev oak oPaw Se av eow dah hehe ae dak So hgeEL Toscana bk Ge goede ab bas 13-6
|
||
14 File Active Objects .............ccssssssccsscsscccsscsecssscssesssscscesssscseessscsesssscssessssesesssseesesesscssssssesesoess 14-1
|
||
PLOCULSOIS ...ceztecceseyeedensebbidietiseede vanes cabin besbedencesaadeueeeddanocna ceuudendcdanosanudevds ov cdertievecevaliy 14-1
|
||
Class: diaeramiit sis 28 athe ea aid Ma al aii hah ci el a ieee eaten ibs 14-1
|
||
FAGTIVE aistectniiais Sevan ha tauicardiaa esavei ial iisarai ni anmaviins onan Aaa reiiney 14-1
|
||
Class Get nat OM ors cecedecdeeeiavscedeee ee ces eiiveceucsdeuel sehvedsuaddeeceadte ecebevngeyesedse sdeneddasunsorsaods 14-2
|
||
PLOPEI ty see cec 552 beasebes beeen aes ates beta yas aac heaved ween ng dou beebedeveaaa dens bevacdandaaa de vdvonudeviaetevubers 14-2
|
||
PACTIVE methods's.c0 3.00.8 neste ie ati eon ie ee oe Ne ae tebe eth Oe oes 14-2
|
||
Thi th alis@ sis; vesecssaceseiadievae cesvevascedaveas degen sau coasvty cesevenrceaevene covuecnacesvaetuessvecaacesvdeda cuiueaaaced 14-2
|
||
Cannel de eect sreouck ccedenstadepenehcvescaukoteyogeta vet eiunedes obetares elu bedeg ueteved eta todes sechevegedabetep cashes 14-2
|
||
Handle: errors suc cecevs caevielbeckecesecni ves aigbetesecaandes taeba bese ddancehaadevdeee Ghavdesdedvedens ovtanoeeenaeyy 14-3
|
||
Close. any, opentiles atx .a.tee ait titan cit ts ai tut al able A aie tt 14-3
|
||
ESCAN fo setosstienich. tei tends eater a tales ear aieianieav aie eniaieie aime eaereliees 14-3
|
||
Class Cetinitl OM, ois. ce.ccieccescintie ccessvsde ces suntecesssheecesans decshanteeceuantsedenadheagesaragoessardanunsodecots 14-4
|
||
POPOL ty s.eeses3hooRades ediv dae ba san be beds vient dou beave duvaenngeeu de vedendanecdeide ony dandaaeuervaveuudevineteoubery 14-4
|
||
FSCAN ‘methods: :. ae. cteecctee vice ache bites abst ace adedaes Woe ahi sleteds aeease satan Saelems chen Gut inns 14-5
|
||
Directory féad +. ssncei eevee eke eee ee eve ee Bi) 14-5
|
||
Process read: COmplett Onis, so. <cessz. ty gut eis etegeces sant tute veubeny ssapstedetes bens seeteedevepecnpsdeesnty os 14-5
|
||
Close directory filés.:.:.cc inca ya tenia chieniini aeiies el aeytee nil anpebeaeits 14-6
|
||
Match a found names. i. civics ces caiad ce aucd ca beeades tisk aaa ca eitaces tvs eas caveeaas Siekeencseedadua veakeae cde 14-6
|
||
Start a:directory scais:.:.iss mass ain eaieidaiaenicattiriniatanierainat ences. 14-6
|
||
Deferred FSCAN methods.............ccccccecesscceeesceeceeneececeeeeeeeenaeeeceenneeesseeeeeeseaeeeeeseateeeenaaees 14-7
|
||
Scan completion y:.23.:2.y3s0s00) aviesteeil davies syed des need ylides needs 14-7
|
||
Next: diftectory name 2.5.8. a00 vic od eat hon ee AR lee ihe eed eto 14-7
|
||
Next file namie si. is.cccecss cess iestcdeedcas cess deaec des cedaceescedasdesceasnccnucaecensectucesvecaucesveaacuuaeaadens 14-7
|
||
Bind: Of SUBGIFECEORY: 5.4 <5, sectenndetet sits testenssetesstegtanteveyedebotegsintedtecesodep saat ethtetehores santa 14-8
|
||
FINODE issiecpsistenseeieiecshesedabe tel begiy sash lpi psaes Bind Tesh ydene Sivas desponb eevee begiaees epee Lay 14-8
|
||
Class Ge tiniti oni is ch Ate ciedete nt dtenst hack oan ctectades bisects saboeaaes bes ean obetetas tick danaseatedua suntan cies 14-9
|
||
PLOPerly sshsieeets Saves rt Ai ethn s Siete ease Patni ai eau eareieeay 14-9
|
||
FNQDE Methods it, c2cec ccedestunvecesetdecesavsdacetstsnedehivnsoeetsdagcdeneradoiebedagstesiyngointetesouugeredeentedes 14-9
|
||
Read from appropriate Channel ......... eee eeeeesseecsseecsseecsseeceseeeesseecsaeecsseeceseeeesaeeesaeers 14-9
|
||
Process read Completion ............:eseseceesceceseeeeseeessseecseecsseecesaeeesaeecsaeecseeseseeeesseessaeers 14-9
|
||
Close both open channels ............cescesscccsseecsseecssceceseeeesseecsaeecseecseesssaeeesseesseesseeeses 14-10
|
||
Starilist SCHETALOM 26: tes santededesses cep eeteshdeset odes sent etedesceeey dees ated leds ect sceda ei ceeeebeebeaeet eg 14-10
|
||
Deferred FNODE methods ...............cccscsscscossnseseessssesensoncecensnseecensusesesenseesseteseecsersseecsnnnees 14-10
|
||
Handle:completed:l sti... 20s. atcteas est cae eho Sisk ee Bichon tak see Sieh oes atewe Baan an ee ts 14-10
|
||
Process:a list tems scsicse. dese ceseccdaceacccdacoundessecancesasvandesessetceassuarceniva cons detecessacde ceaseeanees 14-10
|
||
CAS Ye egectestiics octet cnet ste takers Mes dardep stat rue rath tee tates pat dee stern ete ds tates Oe stall Sarath aa Sty 14-11
|
||
Class definition siccccccsesdevcsccstegeedset cesedsededeedaetcdvviceleseviaabccuy dead cdevdeeb cabeaded caevacee ceuedcvoees 14-11
|
||
Property s..26 sect tte eh a as Se eat Rt eh a eh ited Mat oO Ae eNO a eet son 14-12
|
||
FCASY methods sic. cciicteciesieccciesevtascesevees ceseedarceaescan conendancensacnucebvecne ceneceha cenvedaa cesaeedeenset ea 14-12
|
||
Cancel PEQUeSt x. sssccesdeses dist setseededes edussussevevednssvepacouess votetsdueuetedstededstupedebendedesesupncobeste 14-12
|
||
Read TEQUESEE icsecscccsecaeracsvececcee daaedceuacancenscdandesvedhades uedeedeaus dandeae dosbeabadevbearcdevssanccoeises 14-12
|
||
Write TEQUESE aienied Able AR ed GU Recivte tah etek de aie hdl Muted iin deal ede tet ies 14-12
|
||
Process read or write COMpIeCtiON «0.0... eeeeeeeeceseesneecseecsseeceseecesaecaeecsaeessseessneeeesaes 14-13
|
||
Close the fle so ccecicedecectesscedenvenssvedaaes Deedee de de daeacenedisavusounsehlGedeea We eterenieedets eiuseee res 14-13
|
||
Open a file sssertesovtteeaiydastgiseesteiphes eae Lee plaad ede gn angen ee aip eee 14-13
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Deferred: FOAS Ymethods esis: teeesdugsteectts deus cidsdevsleasduye ius sdees teases ceVadunedeadtunedes sdunedessinbeds 14-14
|
||
Inforin: Of: Completions :..<csadascasieatic aadateatisiacswadariedusaniacsngatsesaaredatonsaneenlasedtess 14-14
|
||
BOS YING oir os cnehieehiden test iocts ch guct boutcah Sigs auch saubicous Stes gues debeaeh sees auch casleses de soavehs ashesuhocwsavede aehhy 14-14
|
||
Class:definition .ciAh aici cidcsiiincs Bonin tidi a dcadias eatin oaNaletehiaa sisal eceactede 14-14
|
||
PLOPETY fess eves ices cies cavbedi eneits tas Sones evaeea chve cuss Be yonnih deverepaaynoetia ceupsvinguooeansduesdevacnneeees tubes’ 14-14
|
||
ECS YNG meth odsyxc:iiostisvicaveailesriaciesattaissestbatoaniaioatiiaeiaoeatieonatiratcecetiaitis 14-15
|
||
Read Pequestt:2.55.chicis icacaet sincegsoivaceuksiehcnebide acne odee ieee ciuksaehceteocaguvhocwatouseteeguekecataey 14-15
|
||
Wile TEQUESt si cosss Jorapscccestieaacrtadeaconsvsauacs sostacmeatoaders Goldeceaspiatedasoseacousteets pvsmeacoessedeeaet 14-15
|
||
15 File Lists ............cscssssssssssssscssscssssssssssesssessscsssecssccsscesscsssasssasssasssasssasssassssessnessnsssasssasssasssesooeees 15-1
|
||
PLeCULSOLS ress vat cate Loss Ses vain cat Leck ot necalecte ties ots nxtndeedekuvk ats Gers tvedebins ace ce tetoate yak ous tuseeeabe tty 15-1
|
||
Class: didetain 2:::sicsisasgiteieiiaeaien ei iva is nian sein aia cave Saini nein: 15-1
|
||
IPS ETE VARs, ceca ssh Pave i eset Oi ait Sites tee oto va ueeat ety oft candeeste Mieaatescaeatete, lathes eat and stetoteaes 15-2
|
||
Class definition » is. ccisctcustetudestisenics cated eed cstedevscabndes vedaodes scabedesds deed salideedusdigneasatiavees 15-2
|
||
PLOPOLEY. Fetish Aire sist oan bbs oak chaeh skeet ch souk ctu painless caunteae e Hiutesh oaWhagea Hates caus see etaadeee dete 15-2
|
||
PSELEVAR methods’. cciics.ccseiediceevscseceescedacensccauceesccdaseascddaseaucdda cosuccadecsucddssvatcaseedencessseetess 15-3
|
||
Compare two records by pOinter .......... cc eeseeeseeecesseecsseeceseecesseeesseecsaeecseeesseeeesaeessaeers 15-3
|
||
PNODE i eseesiicciete ihe aeons Aras iste aves ph era eaieale yan 15-3
|
||
Class: definition is side ccs ih cectett ce. hudeeee vistc conductetes ies cena eves die oes Liem ieee deen c A 15-3
|
||
PLOPerty Mires HsitsrSileaves eet ailentta trainee iste ashe ae ave RUA, 15-3
|
||
PNODE 11@th Od. ois. c2: cadec eds gadasevevnces odes edae sve vedas sdeseddaa devodes otis olessta codesedpeteavvagecstelhyedeseae tes 15-4
|
||
Han dl é errr scicsic.ccscciscteatedsataaeedvad cdevitan cdvedaededvviaes dav deed cdevdean Cdesdsndusevidsvegs viateseviaes cet 15-4
|
||
Handlecompleted listises aces Git acetic eek Gate iene ee ee 15-4
|
||
Process a list 1temis.s i csceivesesevleas cas tarceveisdacess ane eevdelacedcdaususvecdavesecsbavsaceseaesseasves 15-4
|
||
IPS EEL fossa ted ses dite tet ocveest ste s tat ceeveeshatey hot cetteeste dey etetepec taste tee Set oeeieestedes eteyss Peet toy tosis eae 15-4
|
||
Class Gefimition sicciccesicsecotveccndesecdarscevicnnces cans covecaveevsddaadenvadarden cdaaseeut dovdeatddevecabicenes 15-5
|
||
PHOPCLUY. 5 ities sist esec bss dur obss cae btu See obnt oats Suet ove aun teativaunteas cas uesvotaatees audtesivaust ses gbntedus ans 15-6
|
||
PSEL, 1eth Od Siz cvsdsseciveicss ceseiea eccegicaa Seve deans tevecaa ce edcdnses vecdaduawdcdaseaucdaaceaudessevancessevancedeeestces 15-7
|
||
Tint G1 AlaSGs oe, codssivedtevess eotatevcesansexsendsneverdiea se sedlsavsieucs sxnsedasaviueieesduveleveuieetsbewiner aioe a 15-7
|
||
Handle errors: .c.cisiccvacteeesiastics ane caused iancd deed eviaveederbavbetanieveisatdeabidevieveideibevvudenecevics 15-7
|
||
Caricel list: but dit g® ..3 05, secs sees bie son eoeatones tect ot count sdun beste cee bead cguebtsboteetuntogs anebeeesstness 15-7
|
||
Add a file Mame. si. ce..ssicedecesicctvs taatcces ccauceededacesucdausdesccdasesvecddvesucddadeaucdsnevsnccueenstcesves 15-8
|
||
Add -asdirectory Narmes.... fs. sd5, sce A sete testy easbedesotegactpststedesetetanvasustedveedeborepststedpetetorepeas 15-8
|
||
Procéss end..Of a SCAN. isi cecscesticveaces aevkcdbesseccsecdusiesbesandeevederdeseesardesecderdevvadendeaeddensesvecs 15-8
|
||
Build filename Dist... cee cc cicess cectetd owes usa cee diid oeesdant sen caudd oevstaeasercddesedeiacesuaaducdershaedes 15-8
|
||
Ascend one subdirectory level..........eesesescecssecsscecesceeesseecsaeecsacecseecssaeeesaeessaeesseeenes 15-9
|
||
Deéscenid:to: a: subdirectory atu, cecc.z. poten exes pent hte oteg chp sent ote p odes th eaiet eves edeeecegpietedp deeetey nae 15-9
|
||
Sela MEW pathsstatoch ists held ee diene teks bali Ardea eine 15-9
|
||
pensera Tlelistitenie ats ciate litte ctee ihn cee eit eed Beton eed ees 15-9
|
||
Select anode list entry.:.scce:cnrbs cick elie nea wae dinar aie 15-9
|
||
Ascend to the drives level ............:ccccssscceesescceeeeseeeeeeececeeeeseaeeeeesnaeeeenenaeeeeseneeeeeenaeeeess 15-10
|
||
Set/clear a file: tagh. cc: cavaiyitesyshtaeyieideyeeliehighe deere ied peel taeda bd een 15-10
|
||
Geta: tas eed He eke oat Scat sa sees ictacie aad ste ae oat hated acters Hag ems alslor shaten Gastete tea 15-10
|
||
Set the file list: Order on. ccc.ccscccsaseueicssevasccssevancesesvascesedearceveicarccassvancensicancepscetnceswecaa coves 15-10
|
||
Deferred PSEL methods
|
||
Process the completion of list DUIIGING........ eee eeeeeeeeeeesneeeeeeceseesaeecsaeecseesesaeeesaes 15-11
|
||
|
||
|
||
16 File Management Classes.............scsscccssscssssscsssecsssecsssscsssssssssscssssssssssssssssssscsssssssssssssssonseoes 16-1
|
||
PLECUISOLS..ssccs,hsascests shi Sydizasseusctecteidaastontactacanhataspossasteaeadsassestesisaaysesasseanastaavengaess ove 16-1
|
||
Class diasrarn 2.0. fcsitesie hihi ceette dst Subs seis hhh delaeed Rekhaks Helos Eh igaataeed 16-1
|
||
Class defitittioness 2. sieis45.:.situstsaniese Aedes eens es desiasedes A acsestavitess asbestasioers ents 16-3
|
||
PLOPOEey. « csss2iis ccs saves revs shee Ped sanes seis tevsdve Steussua steve dvecesvesvecduve ieasevyaseyedevasussevsacusstuusens Seevses 16-3
|
||
|
||
FMAN method §:c.ci.s2sssccctsstsctasdavientegianeadaapentactacdndasapensactasdandaihtentantaseendsttesteataoeanda eens 16-4
|
||
Initialise the file manager’, 2.05: .s.s0ebssehagieeui cg chteks goheouh sa peaehsvehe quienes oeesaven lhe dveeeuboeehevuas 16-4
|
||
Cancel an outstanding request ......... eee eesceessecesseeeseecsscecseeecesaeecsaeecseeceseeeesaeersaeers 16-4
|
||
Copy files iss siete siv. sees scksson fh Rasteos Taba teesr tain abeTesr ta Algae ev eos Bi 16-5
|
||
Delete: filess.iscirissiccasistiosesdaviccszaciiosandsitois to canesisgs.teataneasastagesteatpeasasiagectastaceabentveaetesy 16-5
|
||
Retiame filess. i303. sectioned id beat ded Se Shes Babee eh 16-6
|
||
Make aidirectory treesesi: i i.ssh- asiesseatises AnphisisssniebeAspdisscnipions sattesessehSdehae aula ae 16-7
|
||
Delete a directory: structure ssi.c.ic:20ssceisissecsistevseet sees eats PuboevbioeesseinPubeevtstevssesndubeevistebets 16-7
|
||
|
||
|
||
CONTENTS
|
||
|
||
|
||
COpy. As CEVACE 2.5 feck zeus Fou stehesees Bove tae Peees fens Pevetues dike ste Febvedussdees Hesgdubs tevstebessedvbstoueeeent hy 16-7
|
||
Formataidevice ssc: iasentetottiaiasscndsisosstesiacontadacelesiaacuntaaaceieseuslackeaeiaaieendeteauicarstom 16-8
|
||
Nate ai evice sre. teicessctt fescict Sevsanchseetonch srvsancs sdesetengevaateneautonehssceanehcasneensiveenensactesensies 16-8
|
||
Set file attributes: si. d sca tiheee wtediescesanie needs vaisteteds ovsediae vada eve adeeseetidiassenaoeandes 16-8
|
||
Deferred FMAN ‘methods ic. 2:ccccsszheecect sing cosadi ne savaceketeradves casa doussuadieasova es sduustewesesateeerciaaes 16-9
|
||
Processin ¢ completed s:isi-s.sdesisssudshicasscsinacssdachcostgaasoeaicathcnatsauocangaaigesteasiocanaeelasienecs 16-9
|
||
Processing a Tew file's: 5iic0is sessed ooh ak fegeek oh ahi eek Sake noe a ek aed 16-10
|
||
Section of processing completed ...........cesceescecsseeceseeeseecsaeecseeesseesesaeeesaeeesaeesseeeees 16-11
|
||
File @xAStS's 225 253 cscva cies sak sdegecues Pevsdca Sdeeeces sduvedes laces sebe Sensbene Fuvbatbedsidaebetedbsibesesstesesulyceeeds 16-11
|
||
Determitie-€rror respOnsess..icsiss-ssdavicissealanssadaheasteslaseaudackeasteaiaceabde seas teaioes sleboasteayst 16-11
|
||
FIMMAK., i, hop ised al ee Re ee Ba eee lea iii ei lied ch eaboths 16-12
|
||
Glass efi ti ON: sess. retebis esas decease vavde ae secedias cate biatsvaedied sais ddaddesedeea obsedkc wsetias svaeeiacees 16-12
|
||
PLOPELLY: sosci cvs teassetstiessc¥s vl sctathvsstescevsccudesvssevadeessevadevssevaduessesdteesauts feunebsteusets sfevacnd eves 16-12
|
||
FIMMK methods 31...tisccrsacsieccstesccesacaitceateassteassattataacneeussanearssausberadascensenaeenacnieoensaaecs 16-12
|
||
Process a make directory request ...........:cesecesssceesseeesnceceseeceseeeesaeecsaeecseeceseeeesaeessaeers 16-12
|
||
EMEMD s.3.so3 erin hisdstneb actin kis Anita Manion Asoosio sti Aateas Vitaos Anat siaanios Aaetaay 16-13
|
||
Gl ass:detim ti Onis cogs 305 bch eens Beiks fad sacks cot subs Ook ache cud Saved ecbaanes Cov tava fubatens Cevioveetenscueesert beds 16-13
|
||
PLOPOLey: sichisisesscssssisseeadshessteshacsudaadeasteseatesediatsoste tassesbdaaieasteginsushdtaoeckasiateedanveesietss 16-13
|
||
BMEMGEP methods x. <: 5st sis 265 Soe ece Se cnckes sazteceh Fasacves santeaeh tana peu keancountas rem dekeweicice oeaetebenctoees 16-13
|
||
Process.a format request:..\.icssco BA sih sti Asis shes Auhasdeaiohahodn shad 16-13
|
||
Process formatting error as ts2. esses c, erties Ba ertitewsievs Ga stus teeta seis tastevet 16-14
|
||
EMSGAN #32 iss .cpede5shteasas lata staansoesnaannpeatastvoeasasea sasbeasvevanases estan ieaes Suess aeatapeeenieeapoeateanensigenss 16-14
|
||
Class: detim iti Oni se. ec. sock cac ares eet se vccnes Sasnecehonenenenes ou caek sacs coentunn cawk gece ewer eoutveseeueceaee 16-14
|
||
PLOPCLEY oss ssdess aati eatiiss Mattias A AspNi aia ketiseani i hAviiiari bn Anni b antes 16-14
|
||
PMSCAN "methods we: sacs ase i} savgscave sue del stuneceds aubedet stuns codhatke Subscene Cevacivebevabeusseva cevedehacetessiaces 16-15
|
||
PLOGCESS AN EITONS, e26scssadavasentaacscaassansoeateatagarsaasoeeiaa sues sulanseestad avasadehedebaauvenestenaeseleneas 16-15
|
||
Wext: fil@ Tames c..0s2 csi: seicart cosececnd oeneuss Secegens donanen asi ceeacd dents a coehgoekewente ce erelgbenaieusicee 16-15
|
||
Next.diréctory: Name-..25.%\sisii hen Msinistiaeiet Mais hain Aaieatt aid Aacmeatndi Macias 16-16
|
||
Hrid Of subditectory ss.:.0ssic:cots2iess o2zideovstawss dasuih ete thors bs thadeaatvesesds dibeeiateesiads hs tevietes 16-16
|
||
Scat: Completion? sy: sssesds.sc ceases cass scatisioeandsi.tesfeateoeatasiage desig easitasseelaaetestenenbasheesl 16-16
|
||
EIMISRG sss bette Seabee chats Sicaeasbcg svat ch heen baad soya cus oeeuboad caubanes Saou oes cauhe Si Siesgocnsaababedeeeseen hte 16-17
|
||
Class definitiGiiin ssscsaceess hai oecseee desea aveaias dh tesati adaes dadoseat vveeee Abeseed oesiens tesactas os 16-17
|
||
PLOPOLLY Sick sevseees cad ceesd eh stees cea atevedeentays svandevs iealeeys reyldevs ius bevya sues Zevsaes Seeyseus SPevsats Seevoous oPey 16-17
|
||
PMSRE methods: .ctsctesiccustsaccatesiacdesdastesatonlecceadasecctaalaccuadateavtaaaceastatearsanaceudatearantas 16-17
|
||
Process: a réad: Complett Oth: 25.254. isievesccessbel aut eotacsshatehaies eouncesscveb badesuecessotehsdehewssonosens 16-17
|
||
EMTARG #3. cM Ssiseistes dio Aoshi shane kvoadiadwa oa kas 16-18
|
||
C2 Fil G10 |W le) 0 Oarmerep eer mere er tree pre en rreerertertcrst rete fr crer pret irre nce orne etree entrar tenes 16-18
|
||
PLOPOLey: vicisassasgceassisg vasa sascvelatus oshesasoassetastosbatasdssaadasaaybesassanned as ovata sesoehadesseatesuaveeiaaa® 16-18
|
||
PMT ARG methods successes ccuetieis Secdeck asiaess icadecheaguevensdeadecheaguesunsdeadevkeshewevcdeedoctedebeonsodes 16-18
|
||
Process a wiite‘COmpletion 4. jiscizs-c.cuscabssshaesdeacithe sees boepseusdtpacess das esesedte,cvapdenesesseuascs 16-18
|
||
File: manager exarnple tenis: icc. 2eisziveie Saves cosbzividel Jaevecustdivsdeh Suavesuetzevsieh Seeeessettuvetel auvsesis tubes 16-19
|
||
17 The LOCS Local File Scan Class............ssssscsssesssessssrssessssssesssessscsssesssesssesssesssesssessscsssessoess 17-1
|
||
PLECULSOTS esis seceigd cess casvace sedan cess dus sacs uceuaevan cuanecancesa seen dsauecae cous sues dvanecaudeuecuavdasnuaaneeseseny 17-1
|
||
Class etinitiOns oie: ce. cesses cseheedesediaecesudtedenichseceeadhsecenadtaeveradtesteneddaczenetiesunnerdasunsceedoes 17-2
|
||
POPE ty Si eseesseecbe asian t ech bee vaee dees Deda w aes ddoude bude vaaen qdeubeobudancane uevvaveusdevieendeesbery 17-2
|
||
LOGS Methods ec seiss cot ces. s idee aed aaka ibaa eet saath tae Woes etd eens iota oem ae ian 17-3
|
||
Perform: a: file:Scatt ccccicsisseciecesiiveiecditeesncessecaecdidesanieasvste ceieudavecaeseae convene cesveete ceaveaacens 17-3
|
||
Check file name:match soo: chic cuceliescasecseecesediescosevetedetadiya cobacndedehutieacunartacdegedesvcusereess 17-3
|
||
Deferred LOCS methods: :a.siscsccceisst cessackiecsvdett cdevicabecovdeae ceeyccabasevacea cdevecsbses veces caeuecsbecedess 17-3
|
||
Process atile name ws. icciessccse, cbcteees iectecneaitlawe cueeean clidbaaes beeeaan cela aes eeeesenedesatea seeesde eds 17-3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TS System: ServiCes:..ccas.sscocssessnnsedessnotessssscesosdoasessesondesendensesensandesendacsesesenodesestsoveeansevesessessnssssenes 18-1
|
||
PRECULESOLS 2 oiys acted cecpestiyedets fa veeo ative date Coa stepaveyo denn deg saueaderonate dea stuusctpeteee dees tapecepedeneteeoes 18-1
|
||
SYSTEM ssciiiintin aaah euisiaR ani ete ae aia loa pane elders 18-1
|
||
Class definition) 68 Aen aside ded eatitbhed abide la aie 18-2
|
||
Property, Hi.cren eset est iti biel hott as eh ais eae eae, 18-2
|
||
SYSTEM Methods. i... cs cnc heerseduvrestadidecssedisceakadededecadeas cotadededededdctatecstadedestinta dedacsevserciaes 18-2
|
||
Initialise si cvvcscvieseesercesecuerdcvvisnedesesderscevisandens sland cvuedandeesadaades dade deauedaedesud dundeanidevesavadene’ 18-2
|
||
Coritrol. 1Compositlonini 83... Sites het ea al Gl Meena Gata 18-2
|
||
|
||
Set link paste server 2isi..i4si.i Ass eavaestis dus eatasies Rita diate dareraiee 18-3
|
||
|
||
Get link Paste :SEVEI sos. f55: ec seet ef geteaeuhy poet ede eoten Sued beet ites teh ieh poiat owe, otep ee daeet eas tense eas 18-3
|
||
Run an application by file Mame ....... eee eeeeeesseeeescecsseeceeceseeeesseecsaeecsaceseeeenaeeesaes 18-3
|
||
|
||
19 Inter-process Commumication...............ssccssccssssccsssscsssscsssecssssssssssssssscsssscsssssssssssssssesssscssssees 19-1
|
||
PLeCUESOLS<: 34 ssatcscicestesierehiaekeestastuecetauveasbes Waa calcbavoavonstegsaacsuvenssasteouasearaeevanateceoneauseecs 19-1
|
||
Inheritance: tree: p23 ces tae es hee keeeasconeeck ene cab ee rhc toch ace lees aceon coameidestectiarenetesed 19-1
|
||
IPCS iiss. ttisid issih tie bienaatien Aoi Asap aliats eisai Ais aighee Aas ad 19-2
|
||
Class*defaniti ons: 2s. cerseiie teens cist sees dek ceeus evel cevades dats cus bcuva (oh cdvxs cae ouweded doves cod duwedeh olaxeees a 19-2
|
||
Property sss chs cidseseessasusscsadeeseecaacistsanaesss sadeciacsssdeasssssesuasovad saveasdeseagebdgaseeckesuaosandaess sae 19-2
|
||
TIRG@S, Methods rics f 5203 cccsect 5 cnctet cencned re nuevos sco cves eynucteseavlcwalee a cteressleredonseeres avnguen sieneeensinees 19-3
|
||
DeStloys sssstoeSAsisids eh Attia Aisa ai snide aslas doa as 19-3
|
||
Tint Ala S65 c2iosscte.vas ete dcoes. te Seendete te oseev' Sena dea dese ae una Gav tbaxseaw dus Cava dyaeeede dune davbtueeee ds tan edes 4 19-3
|
||
Olleue a Messase Tea! sis.cs.shcsssceus sseses..oinadeus seeeeathodesss vs seateatsedelauaceabasieaasteaeaceasasesease 19-3
|
||
Cancel readirequest cis: cei soi abies sence ia heh eared Ske Pen eee A sete bach ad Leeds nb 19-3
|
||
PLOCESS:AMESSA RE oii ss ERs castes st Astesssosstec si dasteics ove teana hsvoasosseasenssemesazoves asset 19-3
|
||
Hain dle error set. sis. ccnaaseiet steseseds eeeet ctevesetcvec tek tees eeiceberet cdeysawacvesdetddeesenttevertes ceeeste 19-4
|
||
Add item:to Server Queue its.i-s.sccacsendasseeeagieaceendatcasteaiaveoadaaiesaiscentlosdoestesitentleedsetass 19-4
|
||
SERVER eoiititissrccshoei Siohesel te ohiesdbges ewuboees ores acdeaul onus ovens dekgaud sess ceebsekeuth sevouevnsdeugoel caveperlbev ih 19-4
|
||
Class de tanitiOniessisfacseiccitus cestissdetadins sets duas dead ea ottadiaideasda va csdeseae edediaa daseuasatosiendeees 19-5
|
||
PLODOLUY, ¢ Peszccvsccss suis cetedeossens teen suetescess desuseedevecessivvedeidveserossceveseisduvesevdevesnseansesessoessee 19-5
|
||
SERV ERsmethodSis.::.scfardesnc cess sie caitast concsutcataaeeccnncaniceaisaunt caxsaneeaasagine uacaeeoaanegeteucaescans 19-5
|
||
DESTLOY Ss sisi f5ch cosh achcistsdetbvciodsadouisietdockscoheuzhe dotouckadeedusbedssdustod gouuute dvsduekedysdechsgeatockegevach 19-5
|
||
|
||
Wii tialaSe.2s 8 hte tetatitien he teat enon ectateaein dana erie bee ee ea ees 19-5
|
||
Haid error ss a2. beucteve dea aeeeaee Rive dea lee geresa deve dun idevstedadebetue baegs dull dees des Saeeaceea tuesdeabeeeede 19-5
|
||
Deferred:SERVER methods .ci.:gs.sosstesiarsendsecstesiatsentasavestasinccuadaaoeutasaccendanseeetesiaccandasiess 19-6
|
||
PLOCESS' A MESSA BE io. oess cca cces seve goes Seunsoes scud vous coues bua cowdgwnd cous Sout cevb even ceva snub desbeuus cesssues estes 19-6
|
||
|
||
20 Link Paste.............sccssccsssscsssscsssecsssecsssesssssscsssscsssscssscssssssssscsssscsssscssssessssssssssesssscsessesossssoseees 20-1
|
||
Precursors. steseik aia aie ee a 20-2
|
||
Class: diagratinns 05 ac sn eet Beit ee ited AOS eat eA BL eA et es 20-2
|
||
LINK CIs ses Saisie Sis eel nei eh ee av a vac eh eral 20-2
|
||
Class: defirinti Onn $5. 5.505,.05, saetgseet scavetessceebaetevese Sodeceesintesutete sostesinteve de doseeep tate deverseesecet ed 20-2
|
||
Property: <6 sischceistaibesivausg lets tesivd shed eed Ree heehee een avin eeobed peesede 20-2
|
||
LINK Clim ethod singe scccisin Jos kit ocbciesd seat odestlen oh ated ted alate dened aided inten ated ts 20-3
|
||
DOSthOYei gs faves hehiccgsvecvdesicted eis ta edea aces ccane tar deiatenseeps tear ieaeceveesi desedeaaeabeny ee ninereeens 20-3
|
||
Trnitiate a tramsaction...........ccccceeccccessscceeeeeseceeeaeeeceecececseaeecceseeeeeeeaeeeeseeeeeseeneeeeeeeeess 20-3
|
||
Request data. :. icici ceisaitccesient ceussae cauiaad canudcboesuvlavecuardea besendesbesas deveiderdevvigergesbeaenaeessde 20-3
|
||
Terminate a transaction ........cccccccccccssssccceseseeeceseeeeseneeecssaceeeeseaeeeeeaeeecssneeesseeeeeeseaeess 20-3
|
||
LINKS 3c oisisiay ad eis eee ets eve ei av ian aie aval ai avers 20-4
|
||
Class: defini ti On iv. cccescceeceessleztedecoteceteessntededadeGertescatededs tag eierd catatedadadevisedarstageteaeiarbendss 20-4
|
||
PLOPOI ly. ss cceccsedniecitecbeteeedaeescatec tobe va caentehbecsvdeh uedevdesnedevdvstensteebuesvvdueb oh esesvedevdeeciebeabeds 20-4
|
||
LINKS Veto sooo cscsien sot AG cectuct ah ese a davtue oat atten teed haste thetsd aitted tect abesied ate 20-5
|
||
Initialise ss ievissreteis shai eStats nieces ei siesta ei baee en elie erate 20-5
|
||
PLOCESS ANINESSA RE cceersdesokatCocgecetevesatateves oust oti vedatccveecatetucodsteuersesedupedetbecgeeutetheedessecerts 20-5
|
||
Deferred LINKSV methods ............cccccecessccceesnceeceeneeeeeeeaeeecesnneeeeseaeeeeesnaeeesseaeeeeessaeeeeneaaees 20-6
|
||
Set data fOrmaticn wo cv cts etetse ite aoe ae teen Gale eh is eae Cee ace 20-6
|
||
Provide datas ccssivcviiic tied ec viadecies cedevsav east tecdeaehu ceveadas cobs tenucenes abesd cchbees wedi eeletaav ees 20-6
|
||
|
||
|
||
CHAPTER 1
|
||
|
||
|
||
INTRODUCTION
|
||
|
||
|
||
This manual is a reference document for Psion's OLIB library. It provides a comprehensive guide to the
|
||
library and documents the classes, methods, properties, inheritance hierarchies and other information
|
||
essential for understanding and using the library. It assumes familiarity with the concepts of Object
|
||
Oriented Programming.
|
||
|
||
|
||
The Object Oriented Programming Guide is a useful pre-requisite as it provides the necessary background
|
||
to Object Oriented Programming as implemented at Psion. It can, of course, be read in conjunction with
|
||
the OLIB Reference manual.
|
||
|
||
|
||
The OLIB library is supplied as the olib.dy] dynamic link library in the ROM of all SIBO machines. It
|
||
contains a collection of classes, built on the services of the PLIB library.
|
||
|
||
|
||
OLIB classes provide a range of services that are independent of the user interface used by an application.
|
||
For example, they include a number of classes for creating array type objects which possess sophisticated
|
||
behaviour.
|
||
|
||
|
||
Use of the OLIB library allows complex applications to be built quickly and reliably. The OLIB object
|
||
classes can be used directly or can be subclassed by any application code. They are both subclassed and
|
||
used directly as components by the user interface libraries (for example, HWIM).
|
||
|
||
|
||
Each chapter in this manual contains a description of either a single class or a number of closely related
|
||
classes. For example, the Variable Array Classes chapter describes a number of classes that implement
|
||
different types of array, each with a variable number of elements, while The TIME Class chapter describes
|
||
a single class.
|
||
|
||
|
||
The description of each class follows the same format. It includes the purpose of the class, the hierarchical
|
||
relationship of the class to other classes, the actual class definition, a description of the property and a
|
||
complete list and discussion of the methods. References to relevant manuals are included if any pre-
|
||
requisite information is needed.
|
||
|
||
|
||
The first chapter contains a description of the Root class, from which all other classes are derived. It is,
|
||
therefore, a required class in all object oriented programs. !
|
||
|
||
|
||
OLIB object classes provide services which include:
|
||
e data storage in a segmented buffer
|
||
e arrays with a variable number of elements
|
||
e basic text editing
|
||
e event management and scheduling
|
||
e time management and timers
|
||
e = file management
|
||
|
||
|
||
e inter-process communication
|
||
|
||
|
||
! Tt is, however, permissible for a category that has no intrinsic dependence on other OLIB classes to
|
||
define its own root class and thereby eliminate all dependency on OLIB. See, for example, the Building a
|
||
Dynamic Library chapter of the Object Oriented Programming Guide.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Using OLIB classes
|
||
|
||
|
||
An application (or DYL) that either subclasses or creates an instance of an OLIB class must declare an
|
||
external reference to the OLIB library in its category file. If, for example, an application's category file has
|
||
the name myprog.cat, the content of this category file must start with the following lines:
|
||
|
||
|
||
IMAGE myprog
|
||
EXTERNAL olib
|
||
|
||
|
||
This ensures that, amongst other things, the defined constants representing the external category numbers
|
||
for the OLIB category (in this case caT_myapp_oL1B) is available to application code. (It is, in any case,
|
||
required in virtually all category files, to provide access to the root class, from which all other classes are
|
||
derived - see the later ROOT class section in this chapter.)
|
||
|
||
|
||
In the source code of the MYPROG application, an instance of an OLIB class - say, of vaszc - would be
|
||
created with p_new (or £_new) as follows:
|
||
|
||
|
||
p_new (CAT_MYPROG_OLIB, C_VASEG) ;
|
||
|
||
|
||
If myprog.cat defines a subclass of an OLIB class (say, the class susvasEc) this would exist in the local
|
||
category. An instance is created using the local category number cat_mypRoG_MypPROG, as follows:
|
||
|
||
|
||
p_new (CAT_MYPROG_MYPROG, C_SUBVASEG) ;
|
||
|
||
|
||
Similar considerations apply to instances created by means of £_newsend.
|
||
|
||
|
||
Notation
|
||
|
||
|
||
Throughout this manual, all references to the Series 3 should be taken to refer to the Series 3a and the
|
||
Workabout, unless explicitly stated otherwise.
|
||
|
||
|
||
Names
|
||
|
||
|
||
Except in class diagrams, a class name is always given in upper case, for example varoot.
|
||
|
||
|
||
The method name in the title line of the description of each method is the defined symbol for the method
|
||
number, without its leading o_. In the body of the text this name, in lower case letters, is used to refer to
|
||
the method function (or more simply, the method) whereas the upper case name refers to the
|
||
corresponding message. Thus, an object's dest roy method function is executed when the object receives a
|
||
DESTROY Message.
|
||
|
||
|
||
Method function prototypes
|
||
|
||
|
||
The description of each method contains a function prototype that specifies the nature of any return value
|
||
and the parameters with which the method is called. The parameters exclude the object handle and the
|
||
method number.
|
||
|
||
|
||
For example, a method for the class var.at with the title line:
|
||
|
||
|
||
VA_TEST Compare two records by pointer
|
||
and prototyped as:
|
||
VOID va_test (UBYTE *precl, UBYTE *prec2) ;
|
||
would be invoked by:
|
||
p_send4 (hand, O_VA_TEST, precl, prec2) ;
|
||
where hand is the handle of an object of the class in question.
|
||
This corresponds to a method function declared in C source code as:
|
||
|
||
|
||
METHOD VOID vaflat_va_test (PR_VAFLAT *self, UBYTE *precl, UBYTE *prec2)
|
||
{
|
||
|
||
|
||
}
|
||
|
||
|
||
1 INTRODUCTION
|
||
|
||
|
||
The & symbol
|
||
|
||
|
||
The enter and leave mechanism (which uses p_enter and p_leave) is commonly used to implement
|
||
structured error recovery. See the Error Handling and Error Recovery chapter of the Object Oriented
|
||
Programming Guide and the Error Handling chapter of the PLIB Reference manual.
|
||
|
||
|
||
Some methods (the vast majority of destroy methods, for example) can never fail and will therefore never
|
||
call p_leave. The title line of a number of the more significant methods of this type are marked with a
|
||
leading © symbol.
|
||
|
||
|
||
With the enter and leave mechanism, a call to p_leave should only occur within the protection of a
|
||
p_enter harness. If p_leave is called outside a p_enter harness, the process will be panicked with panic
|
||
number 47.
|
||
|
||
|
||
The p_leave mechanism and its use in method functions is discussed briefly in the section on Structured
|
||
Error Recovery later in this chapter.
|
||
|
||
|
||
Long parameters
|
||
|
||
|
||
A small number of OLIB class methods require a LoNc or a ULONG parameter. For the reasons explained in
|
||
the Introduction chapter of the Object Oriented Programming Guide, the message-sending mechanism in
|
||
TopSpeed C does not support such parameters and they should be passed as two InT (or UINT) parameters,
|
||
where the first is the least significant word and the second is the most significant word of the data. In such
|
||
a case the actual method prototype is always followed by a conceptual form, illustrating the intent of the
|
||
parameters.
|
||
|
||
|
||
Class diagrams
|
||
|
||
|
||
To illustrate the inheritance and using relationships between classes, most chapters will contain at least
|
||
one class diagram.
|
||
|
||
|
||
The notation is a subset of that used by Grady Booch and described in his book Object-oriented Analysis
|
||
and Design with applications (2nd edition) with two minor changes;
|
||
|
||
|
||
e classes which are referenced, but not described, within a chapter (i.e. classes whose full
|
||
description lies in other chapters of this manual or in a different manual), are underlined,
|
||
|
||
|
||
e the diagrams do not distinguish between 'has' (aggregation) and ‘using’ (client/supplier)
|
||
relationships.
|
||
|
||
|
||
Also note that ultimate inheritance from the root class is assumed and is not shown.
|
||
|
||
|
||
Class hierarchy
|
||
|
||
|
||
In understanding the structure of a specific class, remember that methods and property are often inherited
|
||
from a superclass (or superclasses).
|
||
|
||
|
||
While a class may contain new methods and property, it may also re-define methods inherited from a
|
||
superclass (or superclasses). Note that methods in a superclass can be what are known as deferred
|
||
methods.
|
||
|
||
|
||
To help illustrate these relationships, each class description in this manual is accompanied by a diagram
|
||
which shows that class and its superclass(es) in hierarchical order. This diagram is placed at the
|
||
beginning of the class description.
|
||
|
||
|
||
The diagram consists of a series of adjacent columns. The rightmost column represents the class being
|
||
described and will be marked by a double line border while the column to its left represents its immediate
|
||
superclass (if any) marked by a single line border and so on up the hierarchy. Each column is headed by
|
||
the class name followed by two boxes; the first lists that class's property and the second lists its methods.
|
||
|
||
|
||
Deferred methods are separated from the preceding methods by a blank line and are printed in italics. If a
|
||
class re-defines an inherited method, the method name in the appropriate superclass is written with a line
|
||
through it.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
For example, the following diagram would be included in a description of class cccc subclassed from BBBB
|
||
which itself is subclasses aaaa.
|
||
|
||
|
||
property_1l property_4
|
||
property_2 property_5
|
||
|
||
|
||
method_a method_b
|
||
metheod—b method_c
|
||
method_d method_x
|
||
|
||
|
||
method_e method_y
|
||
method_z
|
||
|
||
|
||
method_u
|
||
|
||
|
||
In this illustration, method_a is supplied by the superclass aaaa, while method_b is replaced in class BBBB
|
||
and further replaced in class cccc. Another method, method_c, is introduced in class BppB but replaced in
|
||
cccc, and so on. Note that method_u is a deferred method.
|
||
|
||
|
||
The root class from which all classes are derived is assumed and will not be shown in the diagrams.
|
||
|
||
|
||
Structured Error Recovery
|
||
|
||
|
||
As mentioned earlier, the enter and leave mechanism is commonly used to implement structured error
|
||
recovery.
|
||
|
||
|
||
Use of the p_leave mechanism
|
||
|
||
|
||
In general, you should assume that all methods NOT marked with the & symbol (as discussed in the
|
||
section on Notation) are capable of calling p_1eave, even if this is not explicitly mentioned in the method
|
||
description. In some cases, such as where a method calls, directly or indirectly, a deferred method (which
|
||
is supplied by a subclasser) it is not possible to specify whether the method may result in p_leave being
|
||
called.
|
||
|
||
|
||
In the event of an error (such as out of system memory) occurring a method may:
|
||
e call p_ieave, passing the (negative) error number,
|
||
e return the error number,
|
||
e either call p_1eave or return an error number, depending on the nature of the error.
|
||
|
||
|
||
Some methods call p_leave (0), which has the effect of returning from the p_enter harness (with the
|
||
return value zero) without signalling an error. This is used, for example, to provide a normal exit from a
|
||
deeply nested function call, without the need for a zero return value to be passed back through the chain of
|
||
calls. Intermediate functions in the chain may then be declared as vorp.
|
||
|
||
|
||
Some method functions that may call p_1eave are declared as vorp. One reason for this may be that the
|
||
method forms part of a chain, as described in the preceding paragraph. If user code were to send such a
|
||
message within a p_enter harness, the value returned from p_enter would be indeterminate if no error
|
||
arose. The solution is to construct a shell function which sends the message and then returns zero, and
|
||
|
||
call this shell within a p_enter harness. The call to p_enter will then return either zero (if the method
|
||
|
||
calls p_leave(0) or it executes to completion) or a negative error number.
|
||
|
||
|
||
1 INTRODUCTION
|
||
|
||
|
||
Panic numbers
|
||
|
||
|
||
See the Error Handling and Error Recovery chapter of the Object Oriented Programming Guide and the
|
||
Error Handling chapter of the PLIB Reference manual for a discussion of panics and panic numbers.
|
||
|
||
|
||
OLIB panics a client that attempts an illegal operation, using the following panic numbers:
|
||
|
||
|
||
Record in flat variable array is out of range
|
||
|
||
Number of record to insert new record before in flat VA is out of range
|
||
Attempt to set capacity of flat VA less than current number of records
|
||
Number of record to delete in flat VA is out of range
|
||
|
||
Record in segmented VA is out of range
|
||
|
||
Outside range of segmented buffer
|
||
|
||
Tried to delete outside segmented buffer
|
||
|
||
Record in string VA whose address is sought is out of range
|
||
|
||
Attempt to set capacity of string VA less than current number of records
|
||
Number of record to insert new record before in string VA is out of range
|
||
Number of record to delete in string VA is out of range
|
||
|
||
Did not read correct number of bytes from resource file
|
||
|
||
Image fails to contain built-in resource file
|
||
|
||
Stray signal death in Application Manager
|
||
|
||
Request to clear area outside character map
|
||
|
||
Bad type/length binary file record header
|
||
|
||
Read on serial port already outstanding or read buffer not allocated
|
||
Serial port read buffer too small for requested read
|
||
|
||
Write to serial port already outstanding or write buffer not allocated
|
||
Serial port write buffer too small for requested write
|
||
|
||
Read on serial port outstanding when tried to see no. of characters available to read
|
||
Read on serial port outstanding when tried to flush serial read buffer
|
||
Read or write outstanding when tried to set serial port characteristics
|
||
Control to set/get not supported
|
||
|
||
OPL translator invoked with empty command line
|
||
|
||
Unrecognised code for setting the console
|
||
|
||
String passed to consol is too long
|
||
|
||
IPCS Message read failed
|
||
|
||
Stray signal death in IPCS server list
|
||
|
||
|
||
CHAPTER 2
|
||
|
||
|
||
THE ROOT CLAss
|
||
|
||
|
||
The root class is the ultimate superclass from which all other classes are derived. It provides the basic
|
||
behaviour which defines a class as being an Object Oriented entity. It contains property which is, in effect,
|
||
the "hook" by which the operating system can keep hold of an instance of a class.
|
||
|
||
|
||
A class must be subclassed from either an existing class or the Root class.
|
||
Class definition
|
||
Defined in category file olib.cat (generated header file olib.g).
|
||
|
||
|
||
CLASS root
|
||
The ultimate superclass - all other classes have root as their ancestor.
|
||
|
||
|
||
{
|
||
ADD destroy
|
||
|
||
|
||
PROPERTY
|
||
{
|
||
P_OBJECT pc; class link
|
||
}
|
||
}
|
||
Property
|
||
root .pe The class link. This should not be accessed by any subclass. This is a data
|
||
|
||
|
||
structure of type p_oBgect which is defined in p_std.h.
|
||
|
||
|
||
The p_oBuect structure is as follows:
|
||
|
||
|
||
typedef struct
|
||
{
|
||
HANDLE hcat;
|
||
HANDLE hclass;
|
||
} P_OBJECT;
|
||
|
||
|
||
where heat and hclass are HANDLE (a synonym for 1nT) data types and have the same meaning as the first
|
||
two words of the p_cuass data structure.
|
||
|
||
|
||
For more information on the underlying mechanisms of the Object Oriented system, see the Object
|
||
Oriented Programming chapter of the PLIB Reference manual and/or the Introduction chapter and the
|
||
appendices of the Object Oriented Programming Guide.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
ROOT methods
|
||
|
||
|
||
J DESTROY Destroy the instance
|
||
|
||
|
||
VOID destroy (VOID) ;
|
||
|
||
|
||
Use the EPOC O/S Libbestroy system service to destroy the instance, together with all component objects
|
||
that are marked for automatic destruction (by means of a PROPERTY n declaration in the class definition).
|
||
|
||
|
||
The destroy method of every subclass must, ultimately, execute Root's destroy method, either by calling
|
||
the root_destroy method function directly or, more usually, by supersending a pestroy message to the
|
||
ROOT.
|
||
|
||
|
||
CHAPTER 3
|
||
|
||
|
||
THE TIME CLAss
|
||
|
||
|
||
to_set
|
||
|
||
to_sense
|
||
to_add_years
|
||
to_add_months
|
||
to_add_days
|
||
to_add_secs
|
||
to_set_format
|
||
to_sense_format
|
||
|
||
|
||
to_get_sysdat
|
||
|
||
|
||
The main purpose of the T1ME class is to convert from one representation of time to another (where the
|
||
word time is used in the general sense, to include the date and the time of day).
|
||
|
||
|
||
The Time class stores a current time within its property. Conversion is done by setting the time in one
|
||
representation with the to_set method and then retrieving the same time in a different representation
|
||
with the to_sense method.
|
||
|
||
|
||
The time class "adds value" to the basic PLIB functions by:
|
||
|
||
|
||
e using its stored state (the current time) to provide a more convenient interface to changing
|
||
between the three PLIB representations of time (system time, P_DAysEc and P_DATE)
|
||
|
||
|
||
e converting to and from textual representations of time (this is not provided by the PLIB
|
||
functions)
|
||
|
||
|
||
As well as the methods associated with conversion, there are methods to add a signed number of years,
|
||
months, days and seconds to the current time.
|
||
|
||
|
||
The time object stores a current time within its property in a p_payseEc struct which contains:
|
||
e the number of days since January Ist 1900 (day 0 is January Ist)
|
||
e the number of seconds in the day
|
||
|
||
|
||
The number of days is stored in a long and can represent dates over a range of about 11.7 million years
|
||
from year 1900. This range of validity is larger than any of the other representations supported.
|
||
|
||
|
||
The property also stores format information that modifies the textual representations of time. A subset of
|
||
the format information is used to interpret textual representations of time.
|
||
|
||
|
||
Although the method descriptions which follow show only English time and date text, the actual text is
|
||
language-dependent. (See the Language and country section of the General System Services chapter of the
|
||
PLIB Reference manual.)
|
||
|
||
|
||
See also uTImE, the HWIM subclass of TIME.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
A knowledge of the PLIB/EPOC time and date functions will aid the understanding of the T1me class. The
|
||
chapter Time, Timers and Dates in the Plib Reference manual contains a description of the basic
|
||
PLIB/EPOC time and date functions and the various formats in use.
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
The time class subclasses root and is defined in the sub-category file time.c/l (with generated header
|
||
file time.g).
|
||
|
||
|
||
CLASS time root
|
||
|
||
|
||
{
|
||
ADD to_set Set the time in a variety of representations
|
||
ADD to_sense Sense the time in a variety of representations
|
||
ADD to_add_years Add years to the current time
|
||
ADD to_add_months Add months to the current time
|
||
ADD to_add_days Add days to the current time
|
||
ADD to_add_secs Add seconds to the current time
|
||
ADD to_set_format Set the format for string representations of time
|
||
ADD to_sense_format Sense the format for string representations of time
|
||
ADD to_get_sysdat Get day/month/suffix/ampm name or system format
|
||
CONSTANTS
|
||
|
||
{
|
||
|
||
SET_TIME_SECONDS 0
|
||
|
||
SET_TIME_DATE 1
|
||
|
||
SET_TIME_DAYSEC 2
|
||
|
||
SET_TIME_NOW 3
|
||
|
||
SET_TIME_DATESTR 4
|
||
|
||
SET_TIME_TIMESTR 5
|
||
|
||
SENSE_TIME_SECONDS 0
|
||
|
||
SENSE_TIME_DATE 1
|
||
|
||
SENSE_TIME_DAYSEC 2
|
||
|
||
SENSE_TIME_STRING 3
|
||
|
||
SENSE_TIME_DATESTR 4
|
||
|
||
SENSE_TIME_TIMESTR 5
|
||
|
||
|
||
SENSE_TIME_FIELDS 0x8000
|
||
|
||
|
||
! Field types
|
||
|
||
FLD_TIME_DAY 0
|
||
|
||
FLD_TIME_MONTH 1
|
||
|
||
FLD_TIME_YEAR 2
|
||
|
||
FLD_TIME_HOUR 3
|
||
|
||
FLD_TIME_MINUTE 4
|
||
|
||
FLD_TIME_SECOND 5
|
||
|
||
FLD_TIME_DAYNAME 6
|
||
|
||
! String format masks
|
||
|
||
PR_TIME_DDMMYY 0x0000
|
||
|
||
PR_TIME_MMDDYY 0x0001
|
||
|
||
PR_TIME_YYMMDD 0x0002
|
||
|
||
PR_TIME_DATE_ORDER 0x0003
|
||
|
||
PR_TIME_NO_DAY 0x0004
|
||
|
||
PR_TIME_NO_MONTH 0x0008
|
||
|
||
PR_TIME_NO_YEAR 0x0010
|
||
|
||
PR_TIME_MONTH_NAME 0x0020
|
||
|
||
PR_TIME_SUFFIX_NAME 0x0040
|
||
|
||
PR_TIME_DAY_NAME 0x0080
|
||
|
||
PR_TIME_NO_CENTURY 0x0100
|
||
|
||
PR_TIME_NO_SECS 0x0200
|
||
|
||
PR_TIME_AMPM 0x0400
|
||
|
||
TY_TIME_DAY 0
|
||
|
||
TY_TIME_MONTH 1
|
||
|
||
TY_TIME_SUFFIX 2
|
||
|
||
TY_TIME_AMPM 3
|
||
|
||
TY_TIME_FORMAT 4
|
||
|
||
! Buffer capacities for strings, including terminating zero
|
||
LN_TIME_DAY_NAME 14 Guaranteed max buffer size for a day name
|
||
LN_TIME_MONTH_NAME 14 Guaranteed max buffer size for a month name
|
||
LN_TIME_DATE_STR 48 Guaranteed max buffer size for a date
|
||
LN_TIME_TIME_STR 12 Guaranteed max buffer size for a time
|
||
|
||
|
||
}
|
||
|
||
|
||
TYPES
|
||
{
|
||
|
||
|
||
3 THE TIME CLASS
|
||
|
||
|
||
typedef struct
|
||
|
||
|
||
{
|
||
|
||
|
||
UWORD flags; date and time format
|
||
UBYTE dsep; date separator
|
||
UBYTE tsep; time separator
|
||
|
||
|
||
} SE_TIME_ FORMAT;
|
||
typedef struct
|
||
|
||
|
||
{
|
||
|
||
|
||
UWORD fld; field type FLD_TIME_XXxX
|
||
TEXT *buf; address of field
|
||
UWORD len; length of field
|
||
|
||
|
||
} SE_TIME_FIELD;
|
||
typedef union
|
||
|
||
|
||
{
|
||
|
||
|
||
TEXT *t;
|
||
|
||
ULONG *1;
|
||
|
||
P_DAYSEC *ds;
|
||
|
||
P_DATE *dt;
|
||
|
||
} PT_TIME_DATA; Address of time data
|
||
|
||
|
||
}
|
||
|
||
|
||
PROPERTY
|
||
{
|
||
|
||
|
||
P_DAYSEC ds; days and seconds
|
||
SE_TIME_FORMAT f; text format
|
||
|
||
|
||
}
|
||
|
||
|
||
}
|
||
Property
|
||
|
||
|
||
time.ds
|
||
|
||
|
||
time.f
|
||
|
||
|
||
TIME methods
|
||
JTO SET
|
||
|
||
|
||
INT to_set (INT format,
|
||
|
||
|
||
the currently set date and time for an instance, in days and seconds, stored
|
||
as two Loncs. It is manipulated by those methods adding or subtracting
|
||
seconds, days, months and years. It should not be changed by any
|
||
subclass.
|
||
|
||
|
||
the currently set textual format and the date and time separator characters
|
||
that will be used when requesting the time and date as a zero terminated
|
||
text string. It should not be directly accessed by any subclass.
|
||
|
||
|
||
Set time
|
||
|
||
|
||
VOID *pdata);
|
||
|
||
|
||
time from a variety of representations of the time. The representation is
|
||
|
||
|
||
pdata Is the address of a uLonc containing the system time. The system time
|
||
is the number of seconds since 00:00:00, January Ist 1970.
|
||
|
||
|
||
pdata is the address of a p_pate structure. See the PLIB manual for a
|
||
description of the p_pate structure.
|
||
|
||
|
||
pdata is the address of a p_paysec structure. See the PLIB manual for a
|
||
description of the p_payssc structure.
|
||
|
||
|
||
uses p_date to set the time to the current system time (pdata is ignored).
|
||
|
||
|
||
Set time's current date and
|
||
specified by format as follows:
|
||
SET_TIME_SECONDS
|
||
SET_TIME_DATE
|
||
SET_TIME_DAYSEC
|
||
SET_TIME_NOW
|
||
SET_TIME_DATESTR
|
||
|
||
|
||
pdata is the address of a string representation of the date (the time of day is
|
||
not changed). The date string should be in numeric form and include the
|
||
day, month and year number in the current order (as defined in the format,
|
||
set using the To_sET_FoRMaT method) and delimited by the current date
|
||
delimiter or any punctuation character. If the year field has two digits and is
|
||
greater than or equal to 70, it is added to 1900; otherwise it is added to 2000.
|
||
If a date is set successfully, the method returns the number of characters
|
||
processed.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
SET_TIME_TIMESTR pdata Is the address of a string representation of the time of day (the date is
|
||
not changed). The time string should contain either two or three fields,
|
||
separated by the current time delimiter or any punctuation character. If there
|
||
are two fields, they are assumed to be hours and minutes and the seconds are
|
||
set to zero. If there is a trailing string which matches the am/pm string
|
||
returned by To_cET_syspar, this is processed with appropriate effect. If a
|
||
time is set successfully the method returns the number of characters
|
||
processed.
|
||
|
||
|
||
If successful (i.e. *pdata defined a legal time), the method returns either zero or, if appropriate, the
|
||
positive number of characters processed. Otherwise the current time is not modified and the method
|
||
returns one of the negative error numbers &_GEN_ARG Or E_GEN_FAIL.
|
||
|
||
|
||
J TO SENSE Sense time
|
||
|
||
|
||
INT to_sense(INT format, VOID *pdata);
|
||
|
||
|
||
Write a partial or complete representation of the current time to *pdata, where the representation depends
|
||
on format as follows:
|
||
|
||
|
||
SENSE_TIME_SECONDS pdata is the address of a utonc to take the current time in system time
|
||
format.
|
||
|
||
SENSE_TIME_DATE pdata is the address of a p_pate structure to take the current time.
|
||
|
||
SENSE_TIME_DAYSEC pdata is the address of a p_payszc structure to take the current time.
|
||
|
||
SENSE_TIME_STRING pdata is the address of a buffer, which must be at least LN_TIME_DATE_STR
|
||
|
||
|
||
bytes in length, to receive a textual representation of the date and time as a
|
||
zero terminated string. The conversion is controlled by the current format, as
|
||
last set by the to_set_format method.
|
||
|
||
|
||
SENSE_TIME_DATESTR pdata is the address of a buffer, which must be at least LN_TIME_DATE_STR
|
||
bytes in length, to take a textual representation of the date as a zero
|
||
terminated string.
|
||
|
||
|
||
SENSE_TIME_TIMESTR pdata is the address of a buffer, which must be at least LN_TIME_DATE_STR
|
||
bytes in length, to take a textual representation of the time of day as a zero
|
||
terminated string.
|
||
|
||
|
||
See the to_get_sysdat method for further information on the size limits for various components of the
|
||
date and time strings.
|
||
|
||
|
||
Returns zero if the time was written successfully to *pdata, or one of the following negative error
|
||
numbers:
|
||
|
||
|
||
E_GEN_UNDER if the current time is too early for the requested format
|
||
|
||
|
||
E_GEN_OVER if the current time is too late for the requested format
|
||
|
||
|
||
J TO_ADD_SECS Add seconds
|
||
|
||
|
||
INT to_add_secs (INT lsw, INT msw);
|
||
INT to_add_secs (LONG nsecs); (conceptual)
|
||
|
||
|
||
Add the signed quantity nsecs to the current time of day. The Lone nsecs is actually passed in the
|
||
message as two INT parameters, 1sw (least significant word) and msw (most significant word).
|
||
|
||
|
||
If the number of seconds added is such as to cross the end (or start, if nsecs is negative) of a day the
|
||
number of days is adjusted accordingly.
|
||
|
||
|
||
The new time of day is set modulo 86400 (the number of seconds in a day).
|
||
|
||
|
||
Returns zero if the adjusted time and date is legal. Otherwise the current time and date are not changed
|
||
and the method returns one of the following negative error numbers;
|
||
|
||
|
||
E_GEN_UNDER if nsecs 1s negative and it would take the time earlier than January Ist 1900
|
||
|
||
|
||
E_GEN_OVER if nsecs is positive and it would take the time later than the latest date which
|
||
can be supported (about 11.7 million years AD)
|
||
|
||
|
||
3 THE TIME CLASS
|
||
|
||
|
||
For example, to add one minute to the current time:
|
||
|
||
|
||
INT AddMinute(PR_TIME *self)
|
||
{
|
||
return (p_send4 (self,O_TO_ADD_SECS, 60,0) );
|
||
}
|
||
|
||
|
||
JTO_ADD DAYS Add days
|
||
|
||
|
||
INT to_add_days (INT lsw, INT msw);
|
||
INT to_add_days(LONG ndays); (conceptual)
|
||
|
||
|
||
Add the signed quantity ndays to the current date. The current time of day is unaffected. The Lone ndays
|
||
is actually passed in the message as two INT parameters, 1sw (least significant word) and msw (most
|
||
significant word).
|
||
|
||
|
||
Returns zero if the new date is legal. Otherwise the current date is not changed and the method returns
|
||
one of the following negative error numbers;
|
||
|
||
|
||
E_GEN_UNDER if ndays 1s negative and it would take the time earlier than January Ist 1900
|
||
|
||
|
||
E_GEN_OVER if ndays is positive and it would take the time later than the latest date which
|
||
can be supported (about 11.7 million years AD)
|
||
|
||
|
||
For example:
|
||
INT AddDays(PR_TIME *self, LONG ndays)
|
||
|
||
|
||
{
|
||
|
||
|
||
INT lsw,msw;
|
||
|
||
|
||
lsw=ndayséOxffff;
|
||
|
||
msw=ndays>>16;
|
||
|
||
return (p_send4 (self, O_TO_ADD_DAYS,1sw,msw) ) ;
|
||
}
|
||
|
||
|
||
JTO_ADD MONTHS Add months
|
||
|
||
|
||
INT to_add_months (INT nmonths) ;
|
||
Add the signed quantity nmonths to the current date. The current time of day is unaffected.
|
||
|
||
|
||
Returns zero if the new date is legal. Otherwise the current date is not changed and the method returns
|
||
one of the following negative error numbers;
|
||
|
||
|
||
E_GEN_UNDER if nmonths is negative and it would take the time earlier than January Ist
|
||
1900
|
||
E_GEN_OVER if nmonths is positive and it would take the time later than the latest date
|
||
|
||
|
||
which can be supported (about 11.7 million years AD).
|
||
|
||
|
||
JTO_ADD YEARS Add years
|
||
|
||
|
||
INT to_add_years (INT nyears);
|
||
Add the signed quantity nyears to the current date. The current time of day is unaffected.
|
||
|
||
|
||
Returns zero if the new date is legal. Otherwise the current date is not changed and the method returns
|
||
one of the following negative error numbers;
|
||
|
||
|
||
E_GEN_UNDER if nyears is negative and it would take the time earlier than January Ist
|
||
1900
|
||
E_GEN_OVER if nyears is positive and it would take the time later than the latest date
|
||
|
||
|
||
which can be supported (about 11.7 million years AD)
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
J TO_SENSE_ FORMAT
|
||
|
||
|
||
VOID to_sense_format (SE_TIME_FORMAT *pf);
|
||
|
||
|
||
Sense format
|
||
|
||
|
||
Write the current format data to «pr. See the to_set_format method for an explanation of the fields in the
|
||
SE_TIME_FORMAT Struct.
|
||
|
||
|
||
It is typically used to obtain the current settings before changing a format field by means of the
|
||
to_set_format method.
|
||
|
||
|
||
J TO_SET_FORMAT
|
||
|
||
|
||
VOID to_set_format (SE_TIME_FORMAT *pf, UINT mask) ;
|
||
|
||
|
||
Set format
|
||
|
||
|
||
Stores format parameters which are subsequently used when converting to and from textual
|
||
representations of time.
|
||
|
||
|
||
If pf is NuLL, the method uses system services to set as many components of the format as possible. It does
|
||
|
||
|
||
this by sending itself a ro_czET_syspaT message with a format of Ty_TIME_FoRmat. In this case the value
|
||
of mask is ignored.
|
||
|
||
|
||
Otherwise, pf should point to an sz_TIME_FORMAT struct.
|
||
|
||
|
||
The values of pf->dsep and pf->tsep should be the new character codes for the required date separator
|
||
and time separator. Either (or both) may be nu, in which case the corresponding existing separator is
|
||
not changed.
|
||
|
||
|
||
The value of pf->flags, together with mask, sets or clears a combination of format flags. Both should
|
||
contain an ored combination of the following bit flags, where the bits set in mask determine which items
|
||
should be changed, and the corresponding bit in pf->£1ags (set or clear) determines the new value. To
|
||
change all bits as specified by pf->f1ags, mask should be set to oxf+. The bit flags have the following
|
||
|
||
|
||
meanings 1n p£->flags:
|
||
|
||
|
||
PR_TIME_DDMMYY if present, the date will be written in day-month-year order (European style)
|
||
|
||
PR_TIME_MMDDYY if present, the date will be written in month-day-year order (USA style)
|
||
|
||
PR_TIME_YYMMDD if present, the date will be written in year-month-day order (Japanese style -
|
||
also good for sorting)
|
||
|
||
PR_TIME_NO_DAY if present, the day is omitted
|
||
|
||
PR_TIME_NO_MONTH if present, the month is omitted
|
||
|
||
PR_TIME_NO_YEAR if present, the year is omitted
|
||
|
||
PR_TIME_MONTH_NAME if present, the month is shown as a name rather than a number
|
||
|
||
PR_TIME_SUFF1IX_NAME if present, a suffix is added to the day number (eg Ist, 2nd, 3rd).
|
||
|
||
PR_TIME_DAY_NAME if set, the day name is written (with a trailing comma) before the date
|
||
|
||
PR_TIME_NO_CENTURY if present, the year is displayed in two digits without the century
|
||
|
||
PR_TIME_NO_SECS if present, the time is displayed without a seconds field
|
||
|
||
PR_TIME_AMPM if present, the time is written in the 12 hour system with a trailing "am" or
|
||
|
||
|
||
"pm" (preferred in the USA), otherwise, it is written using the 24 hour
|
||
system
|
||
|
||
|
||
If setting pR_TIME_DDMMYY, PR_TIME_MMDDYY Of PR_TIME_YYMMDD, no more than one of them should be
|
||
present in pf->flags and all three should be set in mask. (PR_TIME_DDMMyy Is zero so, strictly speaking, it
|
||
does not need to be set in mask. Setting the other two in mask and not including any of them in pf->flags
|
||
has the same effect as including pR_timz_ppmmyvy. For this reason, the constant pR_TIME_DATE_ORDER iS
|
||
defined as a combination of pR_TIME_mMmppyy and PR_TIME_YYMMDD.)
|
||
|
||
|
||
3 THE TIME CLASS
|
||
|
||
|
||
The following example first sets default format data from the current system settings. It then modifies the
|
||
date separator character to a colon (:) and adjusts the time format to include a display of seconds and an
|
||
am/pm indicator:
|
||
|
||
|
||
VOID TimeSetup(PR_TIME *self)
|
||
|
||
|
||
{
|
||
UINT mask;
|
||
SE_TIME_FORMAT f;
|
||
|
||
|
||
p_send4 (self,O_TO_SET_FORMAT,NULL,0); /* set defaults */
|
||
|
||
f.dsep=':';
|
||
|
||
f.tsep=NULL; /* don't change this */
|
||
|
||
£.flags=PR_TIME_AMPM;
|
||
|
||
mask=PR_TIME_NOSECS | PR_TIME_AMPM;
|
||
|
||
p_send4 (self,O_TO_SET_FORMAT, &£,mask); /* clear NOSECS bit and set AMPM bit */
|
||
}
|
||
|
||
|
||
J TO_GET SYSDAT Get system date and time information
|
||
|
||
|
||
INT to_get_sysdat (UBYTE *buf, UINT type, UINT n);
|
||
|
||
|
||
Unless type is TY_TIME_FORMAT, Write a time-related name, as a zero terminated string, to *buf and return
|
||
the length of the string copied.
|
||
|
||
|
||
The caller is responsible for ensuring that the buffer is of sufficient size to take the appropriate string.
|
||
Regardless of the language, each string is guaranteed not to exceed the following lengths:
|
||
|
||
|
||
e aday name will not exceed LN_TIME_Day_Name (14) characters
|
||
e amonth name will not exceed LN_TIME_MoNTH_NaME (14) characters
|
||
|
||
|
||
e any format of date string (built from a combination of items, including those written by this
|
||
method) will not exceed LN_TIME_DATE_sTR (48) characters
|
||
|
||
|
||
e any format of time string (built from a combination of items, including those written by this
|
||
method) will not exceed LN_TIME_TIME_sTR (12) characters
|
||
|
||
|
||
The name type is selected by the value of type, as follows:
|
||
|
||
|
||
TY_TIME_DAY selects the name of the day corresponding to the day number, n (modulo 7)
|
||
TY_TIME_MONTH selects the name of the month where n is the month number (modulo 12)
|
||
TY_TIME_SUFFIX selects the day suffix name where n is the day in month number (modulo 31)
|
||
TY_TIME_AMPM selects the am/pm string where n is 0 for am and 1 for pm (modulo 2)
|
||
|
||
|
||
Although this method may be of use to a client, it is primarily present for internal use when formatting
|
||
date and time strings.
|
||
|
||
|
||
It uses PLIB and operating system services to get the names. A subclass can replace this method if
|
||
alternative names are required.
|
||
|
||
|
||
If type iS Ty_TIME_FoRmaT, the method writes a system-supplied sz_TIME_FoRMAT structure to *buf (with
|
||
no terminating zero) and returns sizeof (SE_TIME_FORMAT) .
|
||
|
||
|
||
The tTy_TIMz_Format type is used by To_sET_rormat when the address of the format data is nuLL.
|
||
Although this type does not really fit with the others, its inclusion here localises the system-dependent
|
||
portion of the time class to this method.
|
||
|
||
|
||
CHAPTER 4
|
||
|
||
|
||
THE SGBUF SEGMENTED BUFFER CLASS
|
||
|
||
|
||
nbytes
|
||
|
||
|
||
cur
|
||
|
||
|
||
destroy
|
||
b_init
|
||
b_point
|
||
b_insert
|
||
|
||
|
||
b_delete
|
||
|
||
|
||
b_compress
|
||
b_ count
|
||
|
||
|
||
b_backpoint
|
||
|
||
|
||
s
|
||
s
|
||
s
|
||
Ss
|
||
sb_extract
|
||
s
|
||
s
|
||
Ss
|
||
s
|
||
|
||
|
||
b_allocseg
|
||
|
||
|
||
Conceptually, the data held in an instance of the scBur class can be regarded as being stored in a variable
|
||
sized linear buffer.
|
||
|
||
|
||
The data is actually stored in memory in a linked list of allocated heap cells of equal size. Insertions and
|
||
deletions may allocate or free cells and will, in general, cause data to be transferred from one cell to
|
||
another. All cells will generally be at least 50% full.
|
||
|
||
|
||
Since the segmentation of the data is largely hidden from a user of scBur, the data should not be accessed
|
||
other than via the supplied methods.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
An understanding of the scBur class will be aided by a knowledge of:
|
||
e the PLIB memory allocator functions.
|
||
|
||
|
||
e =the p_enter and p_leave error handling services.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
The scpur class subclasses root and is defined in the sub-category file varray.cl (with generated header
|
||
file varray.g).
|
||
|
||
|
||
CLASS sgbuf root
|
||
Segmented buffer object
|
||
|
||
|
||
{
|
||
REPLACE destroy
|
||
|
||
|
||
ADD sb_init Initialise with segment length
|
||
|
||
ADD sb_point Get the address from a position
|
||
|
||
ADD sb_insert Insert at specified position
|
||
|
||
ADD sb_delete Delete at specified position
|
||
|
||
ADD sb_extract Extract from specified position
|
||
|
||
ADD sb_compress Compress buffer
|
||
|
||
ADD sb_count Return no. of bytes in buffer
|
||
|
||
ADD sb_backpoint Get the address before a position
|
||
ADD sb_allocseg Allocate memory segments as required
|
||
TYPES
|
||
|
||
|
||
typedef struct
|
||
|
||
|
||
{ Segment header
|
||
P_QUE q; Links to neighbouring segments
|
||
UWORD len; Number of bytes currently in segment
|
||
|
||
|
||
} PR_SGBUF_HD;
|
||
typedef struct
|
||
{
|
||
PR_SGBUF_HD *seg; Current segment, or NULL
|
||
UWORD base; Character position of start of current segment
|
||
UWORD ofs; Current offset into segment
|
||
} PR_SGBUF_SBO;
|
||
}
|
||
|
||
|
||
PROPERTY
|
||
{
|
||
PR_SGBUF_HD hd; Head of queue
|
||
UWORD nbytes; Total number of bytes in buffer
|
||
PR_SGBUF_SBO cur; Current position for efficient positioning
|
||
}
|
||
}
|
||
Property
|
||
sgbuf.hd The head of the linked list of segments containing the data. Also contains
|
||
the length of each allocated segment.
|
||
sgbuf.nbytes The total number of bytes of content.
|
||
sgbuf.cur The last accessed position as the current segment buffer, the character
|
||
|
||
|
||
position of the first character in that buffer and the character offset within
|
||
the buffer. This is used internally for efficient positioning when scanning
|
||
sequentially.
|
||
|
||
|
||
SGBUF methods
|
||
J DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID) ;
|
||
|
||
|
||
Delete the content, freeing all of the allocated segments, and then supersend the pEstrRoy message.
|
||
|
||
|
||
JSB_INIT Initialise
|
||
|
||
|
||
VOID sb_init (UINT len);
|
||
|
||
|
||
Initialise the segment queue and set the required length of a segment by setting sgbuf.hd.1len tO len.
|
||
Note that this is the length to be made available for data. The amount of memory allocated for a segment
|
||
will actually be sgbuf.hd.1en plus the length of the header (i.e. the length of pR_scBuF_HD).
|
||
|
||
|
||
The choice of the value of 1en is a compromise that depends on the nature of the data that is to be stored.
|
||
|
||
|
||
4-2
|
||
|
||
|
||
4 THE SGBUF SEGMENTED BUFFER CLASS
|
||
|
||
|
||
A small value reduces the potentially wasted space within each segment (at worst a segment may be only
|
||
half full) but increases the likelihood that data will need to be moved from one segment to another during
|
||
insertion or deletion. A small segment size is therefore more appropriate when the data is not expected to
|
||
change very frequently.
|
||
|
||
|
||
A larger value of 1en is more suitable for situations where the data will frequently change, but may result
|
||
in more potentially wasted space, particularly if the maximum expected content is small. In addition,
|
||
when data does move from segment to segment, the larger the segment, the more data is likely to be
|
||
moved.
|
||
|
||
|
||
As a rough guideline, it may be noted that all text editing applications on the Series 3 use a segment size
|
||
of 64 bytes. If necessary in a particular case, an optimum value can be found empirically by timing a
|
||
typical operation with a range of different segment sizes.
|
||
|
||
|
||
When a sequence of fixed length items is to be stored, insertion, deletion and access to items will be much
|
||
more efficient if the segment size is an exact multiple of the item size.
|
||
|
||
|
||
No segments are allocated until data is inserted.
|
||
|
||
|
||
J SB POINT Sense data by position
|
||
UINT sb_point (VOID **pbuf, UINT pos);
|
||
Write, to *pbuf, the address of the data at position pos.
|
||
|
||
|
||
Calls p_panic (P_PANIC_P_SGBUF_1) If pos is outside the range of the segmented buffer content.
|
||
|
||
|
||
Updates its internal record of the current position.
|
||
Returns the number of contiguous bytes of data available at *pbut.
|
||
|
||
|
||
Does not write to *pbuf and returns zero if there is no data in the segmented buffer.
|
||
|
||
|
||
SB_INSERT Insert
|
||
|
||
|
||
VOID sb_insert (UINT pos, VOID *pbuf, UINT len)
|
||
|
||
|
||
Create a gap of size 1en bytes at position pos in the segmented buffer and then inserts the 1en bytes of
|
||
data from pbuf.
|
||
|
||
|
||
The inserted data may span more than one segment, with more segments being allocated as necessary. If
|
||
opening the gap causes data to overflow from the segment containing the insertion point, then this data
|
||
will be inserted into the last of any newly created segments and/or any immediately following segment
|
||
that previously existed.
|
||
|
||
|
||
The allocation of segments is performed by sending an sB_ALLOCSEG message.
|
||
The value of sgbuf.nbytes is adjusted to indicate the new number of bytes in the segmented buffer.
|
||
|
||
|
||
Calls p_panic (P_PANIC_P_SGBUF_1) if position pos is outside the range of the segmented buffer.
|
||
|
||
|
||
Inserts nothing and calls p_leave (E_GEN_NoMEMoRY) if it fails to allocate any extra segments required.
|
||
|
||
|
||
JSB_ DELETE Delete
|
||
|
||
|
||
VOID sb_delete(UINT pos, UINT len);
|
||
|
||
|
||
Delete 1en bytes from position pos. This may involve copying data between segments. If a segment
|
||
becomes empty then it will be freed.
|
||
|
||
|
||
The value of sgbuf.nbytes is adjusted to indicate the new number of bytes in the segmented buffer.
|
||
|
||
|
||
Calls p_panic(P_PANIC_P_SGBUF_1) if position pos is outside the range of the segmented buffer. Calls
|
||
p_panic (P_PANIC_P_SGBUF_2) if position pos+1len 1s outside the range of the segmented buffer.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
JSB_EXTRACT Exract
|
||
|
||
|
||
VOID sb_extract (UINT pos, VOID *buf, UINT len);
|
||
|
||
|
||
Copy len bytes of data from position pos into the buffer at bur. If necessary, data is copied from more
|
||
than one segment. The buffer is assumed to be large enough to hold 1en bytes of data.
|
||
|
||
|
||
Calls p_panic (P_PANIC_P_SGBUF_1) if position pos is outside the range of the segmented buffer.
|
||
|
||
|
||
J SB COMPRESS Compress
|
||
|
||
|
||
VOID sb_compress (VOID) ;
|
||
|
||
|
||
Compress the segmented buffer by moving data to fill the early segments. Any segments that are emptied
|
||
by this process will be freed.
|
||
|
||
|
||
J SB COUNT Count characters
|
||
|
||
|
||
UINT sb_count (VOID) ;
|
||
|
||
|
||
Return the number of bytes currently held within the segmented buffer.
|
||
|
||
|
||
J SB _BACKPOINT Sense previous characters
|
||
|
||
|
||
UINT sb_backpoint (VOID **pbuf, UINT pos);
|
||
|
||
|
||
Write, to *pbuf, the address of the byte of data that is the lowest in memory and contiguous with the byte
|
||
at position pos-1. In general, *pbuf will contain the address of the first byte of data in the segment
|
||
containing the byte at position pos. If position pos is at the beginning of a data segment, *pbuf contains
|
||
the address of the first byte of data in the previous data segment.
|
||
|
||
|
||
Returns the number of bytes between the position corresponding to *pbuf and position pos. If the return
|
||
value is n, data is only guaranteed to be valid at addresses of *pbuf to *pbuf+n-1 inclusive.
|
||
|
||
|
||
If pos is zero nothing is written to *pbuf and the method returns zero. This is the only position for which
|
||
the return value is zero.
|
||
|
||
|
||
Calls p_panic(P_PANIC_P_SGBUF_1) if position pos is outside the range of the segmented buffer. This
|
||
method may be regarded as the complement of sb_point and would typically be used when searching
|
||
backwards through the content.
|
||
|
||
|
||
SB_ALLOCSEG Allocate segments
|
||
|
||
|
||
INT sb_allocseg(PR_SGBUF_HD *pseg, UINT nseg);
|
||
|
||
|
||
Allocate a chain of nseg empty segments and insert the chain after the segment at *pseg. Each allocated
|
||
segment is initialised to be empty by setting the 1en field of the segment header to zero. The amount of
|
||
memory required for each segment is sgbuf.hd.1len plus the length of the segment header (i.e. the length
|
||
of PR_SGBUF_HD).
|
||
|
||
|
||
This method is used internally and is not intended to be called by a user of the scBur class.
|
||
|
||
|
||
Does not allocate any segments and calls p_1leave (E_GEN_NOMEMoRY) if there is not enough memory to
|
||
allocate all nseg segments.
|
||
|
||
|
||
CHAPTER 5
|
||
|
||
|
||
VARIABLE ARRAY CLASSES
|
||
|
||
|
||
The classes described in this chapter implement arrays of a variable number of records, in which records
|
||
are referenced by number. The first record is record zero and the last record is record n-1, where n is the
|
||
total number of records in the array. Depending on the particular class, records may be of fixed or variable
|
||
length.
|
||
|
||
|
||
Unlike static C arrays, the space for the array is dynamically allocated from the heap. This means that
|
||
adding a record to an array can fail owing to a failure to allocate additional memory. For some subclasses,
|
||
it is possible to pre-set the capacity; this facility may be used when the required capacity is known in
|
||
advance in order to avoid out of memory failures.
|
||
|
||
|
||
Extending the capacity of an array generally involves either allocating additional heap cells or growing a
|
||
heap cell using p_realloc. This is always done in such a way that the original handle to the object does
|
||
not change.
|
||
|
||
|
||
Precursors
|
||
|
||
An understanding of the variable array classes will be aided by a knowledge of:
|
||
e the PLIB memory allocator functions
|
||
e =the p_enter and p_leave error handling services
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
om
|
||
ae
|
||
|
||
|
||
i varoot /
|
||
|
||
|
||
Ban
|
||
|
||
|
||
Z vaflat / Z sgbuf /
|
||
~ ns) oe + )
|
||
L as 20 aes
|
||
|
||
¢ vaxvars / re
|
||
- )
|
||
Se tees eae
|
||
¢ vaxvar /
|
||
= )
|
||
Lae
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Usage summary
|
||
|
||
|
||
varootT and vaFrrx are abstract classes. varoot defines a relatively large number of deferred methods in
|
||
order to promote polymorphism between the directly usable classes.
|
||
|
||
|
||
The vastr class is used to create arrays of variable length text records, stored as zero terminated strings.
|
||
The storage overhead per string is only one byte, so it is particularly suitable for storing short strings, of
|
||
up to, say, several tens of bytes, or for strings with a wide variation in size (such as file names, which can
|
||
be any length up to 128 bytes, but are usually much shorter). Since the whole array is stored in a single
|
||
allocated cell, the vastr class is most suitable for arrays that contain:
|
||
|
||
|
||
e asmall number of records
|
||
|
||
|
||
¢ amoderately large, but fixed maximum, number of records (for which the maximum capacity can
|
||
be allocated in advance)
|
||
|
||
|
||
Because of its suitability for storing file names, the vastr class is used, for example, to store directory
|
||
listings. In general, however, the vastr class is not particularly suitable for arrays which can dynamically
|
||
grow to a very large size. The resulting repeated calls to p_realloc are likely to cause heap fragmentation
|
||
and seriously reduce the effective use of memory.
|
||
|
||
|
||
The vartat class is used to create arrays of fixed length records, where the whole array is stored in a
|
||
single allocated cell. The preferred usage is as for the vastr class.
|
||
|
||
|
||
The vassc class is used to create arrays of fixed length records where the array is segmented into a
|
||
number of equal sized blocks. It is suitable for large, dynamically changing arrays. Its disadvantage is that
|
||
it takes longer to locate a random record by record number because it has to count through the segments,
|
||
although sequential access to the records is reasonably efficient.
|
||
|
||
|
||
The vaxvar class is used to create arrays of variable length records which, unlike those of the vastr class,
|
||
may contain arbitrary data. It uses an index which is stored in a single allocated cell and thus, like vastR
|
||
and vaFr.art, 1s best suited to arrays containing either a small number of records or a larger but fixed
|
||
number of records. Since each record is stored in a separate allocated cell, it is more suited to the storage
|
||
of longer records, where the increased overhead per record is less significant.
|
||
|
||
|
||
The vaxvars class (which has a segmented index) should be used instead of vaxvar when there is a
|
||
possibility of growth to a large number of records.
|
||
|
||
|
||
Record pointers
|
||
|
||
|
||
Many of the variable array methods take a record pointer prec as a parameter. The va_prec method,
|
||
defined as a deferred method by varoot, and which converts a record number into a prec record pointer,
|
||
assumes that each record is stored in such a way that it is possible to provide a record pointer that is
|
||
equivalent to an external pointer. In most subclasses this assumption is valid. Subclasses that are, because
|
||
of their internal structure, unable to provide a va_prec method may still inherit usefully from varoot, but
|
||
should replace all inherited methods which rely on va_prec (va_findisq, va_search and va_compare).
|
||
|
||
|
||
In most, but not all, subclasses of varooT, prec is the address of the record data. A more general
|
||
interpretation of prec is that it is a handle to a record in the array. In a variable length record array
|
||
subclass, for example, prec might be the address of a string descriptor which contains the address and
|
||
length of a buffer containing the record.
|
||
|
||
|
||
In contrast with va_prec, the va_pbuf method converts a record number into a pointer that is guaranteed
|
||
to point to the record data. Although in most cases (see, for example, varLat and vastTR) va_prec and
|
||
va_pbuf return identical pointers, they would return different addresses in the case mentioned in the
|
||
previous paragraph (see also the vaxvar and vaxvars classes).
|
||
|
||
|
||
In general, there is no guarantee that any method will not cause the data of one or more records to move
|
||
in memory. An application should therefore always access records by record number and should not store
|
||
the pointers supplied by either the va_prec or the va_pbuf method.
|
||
|
||
|
||
When scanning records, the user should not rely on the assumption of contiguous storage to scan through
|
||
the records. Although that is true for some types of variable array, it is certainly not true in general.
|
||
|
||
|
||
None of the supplied methods ever refers to more than two record pointers at any one time. This means
|
||
that the data of a variable array may be stored in a separate segment and only the last two accessed records
|
||
need to be copied into the local data space.
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
VAROOT
|
||
|
||
|
||
VAROOT
|
||
|
||
|
||
destroy
|
||
va_count
|
||
va_delete
|
||
va_sort
|
||
|
||
|
||
va_key
|
||
|
||
|
||
va_findisg
|
||
|
||
|
||
va_insertisq
|
||
|
||
|
||
va_append
|
||
va_insert
|
||
|
||
|
||
va_search
|
||
|
||
|
||
va_compare
|
||
|
||
|
||
va_reset
|
||
|
||
|
||
va_test
|
||
|
||
|
||
va_replace
|
||
|
||
|
||
va_copy
|
||
va_reclen
|
||
va_swap
|
||
|
||
|
||
va_init
|
||
|
||
|
||
va_insertm
|
||
|
||
|
||
va_prec
|
||
|
||
|
||
va_pbuf
|
||
|
||
|
||
va_capacity
|
||
|
||
|
||
va_compress
|
||
|
||
|
||
va_deletem
|
||
|
||
|
||
The varoot class is an abstract class which must be subclassed to provide a usable variable array class.
|
||
|
||
|
||
This abstract class does not assume that the records are of fixed length. It is designed so that it may be
|
||
subclassed by classes in which the records are of either fixed or variable length.
|
||
|
||
|
||
The assumption that prec is a pointer to the record itself is made by only one method in this class -
|
||
va_test. If this assumption is not true for a particular subclass, that subclass should replace va_test with
|
||
a more appropriate method.
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file varray.cl (generated header file varray.g).
|
||
|
||
|
||
CLASS
|
||
|
||
|
||
varoot
|
||
|
||
|
||
root
|
||
|
||
|
||
The root class for variable arrays.
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE destroy
|
||
|
||
|
||
prppprrrrrrere
|
||
GDUUOTGTV00 00D
|
||
|
||
|
||
DEFER
|
||
DEFER
|
||
DEFER
|
||
DEFER
|
||
DEFER
|
||
DEFER
|
||
DEFER
|
||
DEFER
|
||
DEFER
|
||
DEFER
|
||
|
||
|
||
DD va_count
|
||
D va_delete
|
||
|
||
D va_sort
|
||
|
||
D va_key
|
||
|
||
D va_findisq
|
||
|
||
D va_insertisgq
|
||
D va_append
|
||
|
||
D va_insert
|
||
|
||
D va_search
|
||
|
||
D va_compare
|
||
|
||
D va_reset
|
||
|
||
D va_test
|
||
|
||
DD va_replace
|
||
|
||
|
||
va_copy
|
||
va_reclen
|
||
va_swap
|
||
va_init
|
||
va_deletem
|
||
va_insertm
|
||
va_prec
|
||
va_pbuf
|
||
va_capacity
|
||
va_compress
|
||
|
||
|
||
CONSTANTS
|
||
|
||
|
||
{
|
||
|
||
|
||
VA_ROOT_DUPLICATE
|
||
|
||
|
||
VA_ROOT_FLG_FOLD
|
||
VA_ROOT_FLG_DESC
|
||
|
||
|
||
i
|
||
|
||
|
||
Send itself a va_reset message first
|
||
Return record count
|
||
|
||
Delete a record
|
||
|
||
Sort array
|
||
|
||
Set key parameters
|
||
|
||
Find a record in an ordered array
|
||
Insert a record in sequence
|
||
|
||
Append after last record
|
||
|
||
Insert before a record
|
||
|
||
Search for a match
|
||
|
||
Compare two records
|
||
|
||
Reset to zero records and capacity
|
||
Compare a record with a test record
|
||
Replace a record
|
||
|
||
Copy a record
|
||
|
||
Return record length
|
||
|
||
Swap two records
|
||
|
||
Initialise an array
|
||
|
||
Delete a record range
|
||
|
||
Insert a record sequence
|
||
|
||
Return the address of record n
|
||
Point at the buffer data - usually same as prec
|
||
Set record capacity
|
||
|
||
Compress memory usage
|
||
|
||
|
||
1
|
||
Ox01
|
||
0x02
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TYPES
|
||
|
||
|
||
{
|
||
typedef struct
|
||
{
|
||
|
||
|
||
UBYTE ofs; offset for comparison
|
||
|
||
UBYTE len; length for bcmp (scmp if zero)
|
||
UBYTE fold; fold case if set
|
||
|
||
UBYTE desc; reverse compare result if set
|
||
|
||
|
||
} PR_VAROOT_KEY;
|
||
}
|
||
|
||
|
||
PROPERTY
|
||
{
|
||
UWORD nrec; number of records in the array
|
||
PR_VAROOT_KEY key; defines key for sort etc
|
||
}
|
||
}
|
||
|
||
|
||
Property
|
||
varoot.nrec Holds the current record count. Each subclass is expected to maintain this
|
||
field.
|
||
varoot .key Holds the current sort key. See the va_key method for a description of the
|
||
|
||
|
||
PR_VAROOT_KEYy Structure fields.
|
||
|
||
|
||
VAROOT methods
|
||
& DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID)
|
||
|
||
|
||
Destroy the array by sending itself a va_RESET message before supersending a DESTROY message.
|
||
|
||
|
||
& VA_COUNT Count records
|
||
|
||
|
||
UINT va_count (VOID)
|
||
|
||
|
||
Return the number of records in the array from varoot .nrec.
|
||
|
||
|
||
VA_APPEND Append a record
|
||
|
||
|
||
VOID va_append(VOID *prec)
|
||
Append the record pointed to by prec to the end of the array.
|
||
|
||
|
||
This is done by sending itself a va_INSERT message to insert the record at a position given by
|
||
|
||
|
||
varoot.nrec.
|
||
|
||
|
||
It will call p_1eave if the va_insert method for that particular subclass calls p_leave, for example, if it
|
||
fails to allocate any necessary additional memory.
|
||
|
||
|
||
VA_INSERT Insert a record
|
||
|
||
|
||
VOID va_insert (UINT recno, VOID *prec) ;
|
||
Insert the record pointed to by prec before record recno.
|
||
|
||
|
||
This is done by sending itself a va_INSERTM message with recno, prec and 1 (i.e. one record) as
|
||
parameters.
|
||
|
||
|
||
It will call p_teave if the va_insertm method for that particular subclass calls p_1eave, for example, if it
|
||
fails to allocate any necessary additional memory.
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
& VA_DELETE Delete a record
|
||
|
||
|
||
VOID va_delete(UINT recno);
|
||
|
||
|
||
Delete record recno from the array by sending itself a va_DELETEM message with recno and 1 (i.e. one
|
||
record) as parameters.
|
||
|
||
|
||
& VA_KEY Set key for comparisons
|
||
|
||
|
||
VOID va_key(UINT offset, UINT length, UINT flags);
|
||
|
||
|
||
Define the parameters which are used by va_test and, indirectly, by va_compare, va_sort, va_findisq
|
||
and va_insertisq.
|
||
|
||
|
||
The parameters are:
|
||
|
||
|
||
offset - sets the offset (0 to 127 inclusive) into the record at which the comparison begins. The value
|
||
is copied into varoot.key.ofs.
|
||
|
||
|
||
length - if non-zero, this sets the length of the comparison (1 to 127 inclusive) and, if zero, sets the
|
||
comparison to be between two zero terminated strings. The value is copied into varoot.key.len.
|
||
|
||
|
||
flags - any combination of the two flags va_RooT_FLG_FOLD and va_RooT_FLG_DEsc. If the
|
||
VA_ROOT_FLG_FOLD flag is set, the comparison is case independent. If the va_Root_FLG_pEsc flag
|
||
is set, the result of the comparison is reversed, to give descending rather than ascending order.
|
||
The values of flags&VA_ROOT_FLG_FOLD and flags&VA_ROOT_FLG_DESC are copied into
|
||
varoot .key.fold and varoot .key.desc respectively.
|
||
|
||
|
||
The default settings are offset = 0, length = 0, flags = 0, giving ascending order, case-dependent
|
||
string comparisons, from offset zero in the record buffer.
|
||
|
||
|
||
See the va_test method for further discussion of the va_key parameters.
|
||
|
||
|
||
& VA_TEST Compare two records by pointer
|
||
|
||
|
||
INT va_test (VOID *precl, VOID *prec2);
|
||
|
||
|
||
Compare the record pointed to by prec2 with the record at preci on the assumption that the records
|
||
contain text. The basis for the comparison is subject to the contents of varoot .key, as set by the method
|
||
va_key, aS follows:
|
||
|
||
|
||
if varoot .key.len==0 it uses
|
||
p_scmp df varoot.key.fold is FALSE), or
|
||
p_scmpi af varoot.key.fold is TRUE).
|
||
|
||
|
||
if varoot .key.len>0 it uses
|
||
p_bemp (if varoot .key. fold iS FALSE), OF
|
||
p_bcempi af varoot.key.fold is TRUE).
|
||
|
||
|
||
The default is to use p_scmp.
|
||
|
||
|
||
Returns the logical equivalent of (*preci-*prec2) - that is, zero if the two records are equal, negative if
|
||
*prec1 is before (less than) *prec2, positive if after. If key. desc is TRUE this result is reversed.
|
||
|
||
|
||
This method is used directly by va_findisg, va_search and va_compare. It is used indirectly by va_sort
|
||
and va_insertisq.
|
||
|
||
|
||
Subclasses which are unable to provide va_prec, or in which va_prec does not return a pointer to the
|
||
data to be compared, must replace this method.
|
||
|
||
|
||
& VA_COMPARE Compare two records by number
|
||
|
||
|
||
INT va_compare(UINT nl, UINT n2);
|
||
|
||
|
||
Compare record ni with record n2 by sending itself va_pREc messages to get pointers to the records and
|
||
then sending itself a va_tEst message to perform the comparison that determines the return value.
|
||
|
||
|
||
Returns the logical equivalent of n1-n2, that is, zero if the two records are equal, a negative value if record
|
||
n1 is less than (before) record n2 or a positive value if record ni is greater than (after) record n2. Note the
|
||
effect of the va_RooT_FLG_FOLD and va_ROoT_FLG_pDEsc flags.
|
||
|
||
|
||
This method is used directly by va_sort.
|
||
|
||
|
||
Subclasses which are unable to provide va_prec must replace this method.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
VA_SORT Sort
|
||
|
||
|
||
VOID va_sort (VOID)
|
||
Sort the records of the array.
|
||
|
||
|
||
The sort uses the quicksort algorithm. This is an efficient exchange sort using va_compare and the
|
||
deferred va_swap respectively to compare and to exchange two records.
|
||
|
||
|
||
Subclasses which are unable to implement va_swap efficiently should either not support va_swap or
|
||
subclass va_sort to sort by some other means. Not supporting va_swap does not mean that the array may
|
||
never be ordered; ordered arrays can still be constructed using va_insertisq.
|
||
|
||
|
||
The method uses va_compare (and hence va_test) to compare two records. The sort key is determined by
|
||
va_test, as qualified by the last use of va_key. If the flexibility afforded by va_key is insufficient (for
|
||
example, to sort on multiple keys) va_test may be replaced.
|
||
|
||
|
||
Note that the vastr class does not support this method. In such a case the array may be built in order, by
|
||
using the va_insertisq method.
|
||
|
||
|
||
& VA_FINDISQ Find (binary chop)
|
||
|
||
|
||
INT va_findisq(VOID *pkey, VOID *pmid) ;
|
||
|
||
Find a record in an ordered array, using the binary search algorithm.
|
||
|
||
The record to be found is specified by pkey which is typically a record pointer (prec).
|
||
|
||
Returns zero if an exact record match is found, with the record number of the matching record in *pmia.
|
||
|
||
|
||
If there is no matching record, *pmid contains the record number of one of the two records adjacent to the
|
||
key and va_findisg returns the logical equivalent of *pkey-*pmid, that is, a negative value if *pkey is
|
||
less than (before) the existing record with record number *pmia, or a positive value if *pkey is greater
|
||
than (after) record number *pmid.
|
||
|
||
|
||
The method uses va_test, passing pkey as the first parameter; the second is a pointer to one of the
|
||
records in the ordered variable array and is determined by the binary search algorithm itself as it works
|
||
through its search.
|
||
|
||
|
||
The result will be unpredictable if the array is not ordered. (An array may be ordered either by applying
|
||
va_sort or by using va_insertisgq to build the array.)
|
||
|
||
|
||
VA_INSERTISQ Insert in sequence
|
||
|
||
|
||
INT va_insertisq(VOID *prec,UWORD *precno) ;
|
||
|
||
|
||
Insert the record pointed to by prec in sequence into an ordered array using va_findisg to locate the
|
||
insertion point.
|
||
|
||
|
||
If there is no matching record, it sends itself a va_INnsERTm message. If the insertion is successful, the
|
||
record number of the inserted record is written to *precno and va_insertisq returns zero.
|
||
|
||
|
||
The record is not inserted if there is already a matching record in the array (that is, if va_compare would
|
||
return zero). In this case va_insertisq returms VA_ROOT_DUPLICATE (which is a positive number) and
|
||
writes the matching record number to *precno.
|
||
|
||
|
||
Since it sends a vA_INSERTM message, it is quite possible for the insert to fail with out of memory and call
|
||
|
||
|
||
p_leave.
|
||
|
||
|
||
© VA_SEARCH Search
|
||
|
||
|
||
INT va_search(VOID *pkey) ;
|
||
Sequentially search for a record which exactly matches that specified by pkey.
|
||
|
||
|
||
The search is performed by sending a va_tEsT message to compare each record in the array (obtained by
|
||
use Of va_prec) with the data pointed to by pkey, which is assumed to be a record pointer.
|
||
|
||
|
||
Returns the record number if found (+ve number or zero) or E_GEN_FAIL if not.
|
||
|
||
|
||
5-6
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
& VA_RESET Reset
|
||
|
||
|
||
VOID va_reset (VOID)
|
||
|
||
|
||
Reset the array to its state just after its creation (and, if appropriate, a va_init). Following a va_reset the
|
||
array contains no records and has no record capacity.
|
||
|
||
|
||
The method is implemented by sending itself a va_bzELETEM message to delete varoot .nrec records,
|
||
starting from record 0. This is followed by a va_compress message to discard all record capacity.
|
||
|
||
|
||
The method has two principal uses:
|
||
|
||
|
||
e It provides the client with a concise and efficient way to delete all records in the array and, at the
|
||
same time, to zero the capacity.
|
||
|
||
|
||
e itis used by the destroy method to remove all allocated cells, other than the object instance cell,
|
||
prior to the freeing of the instance itself.
|
||
|
||
|
||
This implementation assumes that the va_compress method always frees all additional allocated cells
|
||
when an array contains no records. (This assumption is true for all OLIB array classes.)
|
||
|
||
|
||
VA_REPLACE Replace a record
|
||
|
||
|
||
VOID va_replace(UINT recno, VOID *prec);
|
||
Replace record number recno with the record pointed to by prec.
|
||
|
||
|
||
The method is implemented by using a va_DELETE message to delete record recno, followed by a
|
||
VA_INSERT message to insert prec at position recno.
|
||
|
||
|
||
The implementation of this method is aimed at variable length record subclasses; fixed length record
|
||
subclasses can replace it by a more efficient method (for example, by simply overwriting the record data).
|
||
|
||
|
||
Deferred VAROOT methods
|
||
& VA_COPY Copy a record
|
||
|
||
|
||
UINT va_copy(UINT recno, VOID *prec);
|
||
A deferred method for copying the contents of record recno tO prec.
|
||
Returns the length copied.
|
||
|
||
|
||
Not used by any methods in this class but deferred, to promote polymorphic subclasses.
|
||
|
||
|
||
& VA_RECLEN Get record length
|
||
UINT va_reclen(UINT recno);
|
||
A deferred method for returning the record length of record recno.
|
||
|
||
|
||
Not used by any methods in this class but deferred, to promote polymorphic subclasses.
|
||
|
||
|
||
VA_SWAP Swap two records
|
||
|
||
|
||
VOID va_swap(UINT nl, UINT n2);
|
||
A deferred method for swapping the contents of record n1 with those of record n2.
|
||
|
||
|
||
Used by va_sort.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
VA_INIT Initialise
|
||
|
||
|
||
VOID va_init(...)
|
||
A deferred method for initialising the property of the newly created array.
|
||
|
||
|
||
No record capacity is allocated until the first record insertion or va_capacity message. All subclasses
|
||
should ensure that this is the case. However, the method may still fail, calling p_1eave (&_GEN_NOMEMORY)
|
||
if the subclass has other memory requirements (vasec, for example, creates a component object).
|
||
|
||
|
||
The parameters depend upon the subclass. For example, a fixed length record subclass would require the
|
||
record length as a parameter.
|
||
|
||
|
||
Not used by any methods in this class but deferred, to promote polymorphic subclasses.
|
||
|
||
|
||
VA_CAPACITY Set capacity
|
||
|
||
|
||
VOID va_capacity(UINT nspc);
|
||
A deferred method for setting the capacity of the internal storage.
|
||
|
||
|
||
The interpretation of the parameter nspc is dependent on the subclass. For example, nspc might
|
||
reasonably be the number of records in a fixed length record subclass, or it might be the total number of
|
||
bytes of allocated storage in a variable length record subclass.
|
||
|
||
|
||
It is not always possible to provide this method in a meaningful way and some subclasses are expected to
|
||
dummy it.
|
||
|
||
|
||
Not used by any methods in this class but deferred, to promote polymorphic subclasses.
|
||
|
||
|
||
VA_COMPRESS Compress
|
||
|
||
|
||
VOID va_compress (VOID) ;
|
||
|
||
|
||
A deferred method for compressing the capacity of the array as much as is reasonable and sensible (this
|
||
judgement is left to the subclass).
|
||
|
||
|
||
The supplied destroy method assumes that va_compress frees all allocated cells used to hold records
|
||
when there are no records in the array. If this is not true, the destroy method must be subclassed.
|
||
|
||
|
||
The va_compress method is used directly by va_reset and indirectly by destroy.
|
||
|
||
|
||
VA_DELETEM Delete sequence of records
|
||
VOID va_deletem(UINT recno, UINT nrecs);
|
||
A deferred method for deleting nrecs records, starting with record number recno.
|
||
|
||
|
||
Used directly by va_delete and va_reset and indirectly by destroy.
|
||
|
||
|
||
VA_INSERTM Insert sequence of records
|
||
VOID va_insertm(UINT recno, VOID *prec, UINT nrecs) ;
|
||
A deferred method for inserting a sequence of nrecs records, pointed to by prec, before record recno.
|
||
|
||
|
||
If it fails to allocate enough memory to hold the new records it should allocate nothing and call p_leave
|
||
since, typically, va_insert and va_append are void functions and va_insertisq returns an insertion
|
||
indicator.
|
||
|
||
|
||
Used directly by va_insert and indirectly by va_append and va_insertisq.
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
VA_PREC Point to record
|
||
|
||
|
||
VOID *va_prec(UINT recno);
|
||
A deferred method for returning a pointer to record recno.
|
||
See the introductory discussion of the varoot class for the meaning of a record pointer.
|
||
|
||
|
||
Used directly by va_compare, va_findisg and va_search, and indirectly by va_insertisq and va_sort.
|
||
|
||
|
||
VA_PBUF Point to record data
|
||
|
||
|
||
VOID *va_pbuf (UINT recno);
|
||
A deferred method for returning a pointer to the record data of record recno.
|
||
|
||
|
||
Typically, it returns the same value as for va_prec. in some classes, however, the record pointer may not
|
||
be the same as the record data pointer (this is true for the vaxvar and vaxvars classes) or the record may
|
||
contain a header to the data.
|
||
|
||
|
||
The va_pbuf method should always be used in preference to va_prec when a pointer to the data of the
|
||
record is required.
|
||
|
||
|
||
VAFIX
|
||
|
||
|
||
VAROOT
|
||
|
||
|
||
destroy va_replace
|
||
va_count va_copy
|
||
va_delete va_reclen
|
||
va_sort va_swap
|
||
|
||
|
||
va_key
|
||
|
||
|
||
va_findisgq va_init
|
||
|
||
|
||
va_insertisq va_deletem
|
||
va_append va_insertm
|
||
va_insert va_prec
|
||
va_search va_pbuf
|
||
va_compare va_capacity
|
||
va_reset va_compress
|
||
|
||
|
||
va_test
|
||
|
||
|
||
The varrx class is an abstract class for fixed length record variable arrays. In addition to adding the
|
||
record length rien to the property, it:
|
||
|
||
|
||
e implements the deferred methods va_swap, va_copy and va_reclen.
|
||
e replaces va_replace by a more efficient method.
|
||
|
||
|
||
The methods are provided on the assumption that the record pointer prec is simply the address of the
|
||
record (reasonable when records are of fixed length).
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file varray.cl (generated header file varray.g).
|
||
CLASS vafix varoot
|
||
|
||
|
||
Fixed length record variable arrays.
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE va_replace More efficient than varoot's
|
||
REPLACE va_swap Uses p_bswap
|
||
REPLACE va_copy Uses p_bcpy
|
||
REPLACE va_reclen Returns property value
|
||
PROPERTY
|
||
{
|
||
UWORD rlen; Record length
|
||
}
|
||
}
|
||
Property
|
||
vafix.rlen the record length, set by a subclass va_init method. Each subclass is
|
||
|
||
|
||
expected to set this field.
|
||
|
||
|
||
VAFIX methods
|
||
& VA_REPLACE Replace a record
|
||
|
||
|
||
VOID va_replace(UINT recno, VOID *prec);
|
||
|
||
|
||
Replace the specified record by sending itself a va_pREc message to convert recno into a record pointer
|
||
and then using p_bcpy to overwrite that record with the record at prec.
|
||
|
||
|
||
& VA_COPY Copy a record
|
||
|
||
|
||
UINT va_copy(UINT recno, VOID *prec);
|
||
|
||
|
||
Copy the specified record to prec by sending itself a va_pREc message to convert recno into a record
|
||
pointer and then using p_bcpy to copy that record data from the array to prec.
|
||
|
||
|
||
Returns the length copied.
|
||
|
||
|
||
& VA_RECLEN Get record length
|
||
|
||
|
||
UINT va_reclen (VOID)
|
||
|
||
|
||
Return the record length, that is, the value of the vafix.rlen property field.
|
||
|
||
|
||
& VA_SWAP Swap two records
|
||
|
||
|
||
VOID va_swap (UINT n1,UINT n2)
|
||
|
||
|
||
Swap the contents of record n1 with record n2 by sending two va_prEc messages to itself to turn n1 and n2
|
||
into record pointers and then using p_bswap to swap the record contents.
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
VASTR
|
||
|
||
|
||
VAROOT
|
||
|
||
|
||
key
|
||
|
||
|
||
destroy va_replace va_copy
|
||
va_count va_reclen
|
||
va_delete va_init
|
||
va_sort va_deletem
|
||
|
||
|
||
va_key va_insertm
|
||
|
||
|
||
va_findisgq Ad va_prec
|
||
|
||
|
||
va_insertisq va_pbuf
|
||
va_append i va_capacity
|
||
va_insert va_compress
|
||
va_search
|
||
|
||
va_compare
|
||
|
||
va_reset
|
||
|
||
|
||
va_test
|
||
|
||
|
||
The vastr class may be used to create arrays of variable length text records which are stored as zero
|
||
terminated strings. Non-textual data may be used provided that the record data does not have any zero
|
||
bytes in it.
|
||
|
||
|
||
The whole array is stored in a single allocated cell. When a record is inserted into a full array, the single
|
||
cell is reallocated to accommodate the additional record. Deletions do not automatically reduce the record
|
||
capacity, but the capacity may be reduced manually using va_compress Of va_capacity.
|
||
|
||
|
||
The record pointer prec points to a zero terminated string. Internally, the records are stored as a
|
||
contiguous sequence of zero terminated strings.
|
||
|
||
|
||
To locate a random record by record number, va_prec has to count through the records. However, the
|
||
object remembers the last record accessed so that scanning the array sequentially from the first record is
|
||
reasonably efficient.
|
||
|
||
|
||
The vastr class is suitable for short arrays or for large arrays which have a known maximum capacity (in
|
||
terms of the number of bytes required). It is not suitable for arrays which can dynamically grow to a large
|
||
size because heap fragmentation can seriously reduce the effective use of the heap.
|
||
|
||
|
||
The string array is especially suitable for strings that can vary greatly in size since the overhead per string
|
||
(1 byte) is small. A typical use is for holding file name lists where each string can have a maximum
|
||
length of p_rwames1zE (128) bytes but is usually less than 32 bytes long.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file varray.cl (generated header file varray.g).
|
||
|
||
|
||
CLASS
|
||
|
||
|
||
vastr varoot
|
||
|
||
|
||
Variable length text record variable arrays
|
||
|
||
|
||
REPLACE va_copy
|
||
REPLACE va_reclen
|
||
REPLACE va_init
|
||
REPLACE va_compress
|
||
REPLACE va_capacity
|
||
REPLACE va_deletem
|
||
REPLACE va_insertm
|
||
REPLACE va_prec
|
||
REPLACE va_pbuf=vastr_va_prec
|
||
PROPERTY
|
||
{
|
||
UWORD size; current size of the array in bytes
|
||
UWORD gran; re-alloc granularity
|
||
UBYTE *base; base of the array
|
||
UWORD len; offset to end of used data
|
||
UWORD num; number of last record referenced
|
||
UBYTE *pnum; pointer to record num
|
||
}
|
||
}
|
||
Property
|
||
vastr.size The current size of the allocated cell that contains the data. It should not
|
||
be accessed by any subclass.
|
||
vastr.gran The granularity, in bytes, used when expanding the allocated cell. It
|
||
|
||
|
||
vastr.base
|
||
|
||
|
||
vastr.
|
||
|
||
|
||
vastr.
|
||
|
||
|
||
vastr.pnum
|
||
|
||
|
||
len
|
||
|
||
|
||
num
|
||
|
||
|
||
should not be accessed by any subclass.
|
||
The allocated cell base. It should not be accessed by any subclass.
|
||
|
||
|
||
The byte offset from vastr.base to the end of the data in the allocated
|
||
cell. It should not be accessed by any subclass.
|
||
|
||
|
||
The record number of last record referenced. It should not be accessed by
|
||
any subclass.
|
||
|
||
|
||
A pointer to the record specified by vastr.num. It should not be accessed
|
||
by any subclass.
|
||
|
||
|
||
VASTR methods
|
||
© VA_INIT Initialise
|
||
|
||
|
||
VOID va_init (UINT granularity)
|
||
|
||
|
||
Initialise the array by setting vastr.gran to the passed granularity, which must be at least as large as
|
||
the longest record to be inserted. No capacity is actually allocated until the first insertion.
|
||
|
||
|
||
The granularity is significant when an insertion requires an increase in capacity; the increase is such that
|
||
the capacity, in bytes, is made an exact multiple of the granularity. Making this value larger means that
|
||
the array cell needs to be reallocated less frequently as a result of insertions, but more memory may be
|
||
wasted in unused capacity. Any unused capacity may be recovered by sending a va_comPpRESS message
|
||
when the building of an array is complete.
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
VA_CAPACITY Set capacity
|
||
|
||
|
||
VOID va_capacity(UINT nspc);
|
||
|
||
|
||
Set the capacity of the allocated array cell by reallocating it to have exactly the capacity for nspc bytes (the
|
||
granularity has no effect).
|
||
|
||
|
||
The minimum space required is equal to the sum of the string lengths of all the records plus one byte per
|
||
record for the terminating zero.
|
||
|
||
|
||
Calls p_panic (P_PANIC_P_VASTR_2) If nspc is less than the current size of the array.
|
||
|
||
|
||
& VA_COMPRESS Compress
|
||
|
||
|
||
VOID va_compress (VOID)
|
||
|
||
|
||
Compress the capacity of the array to that which will exactly contain the current records by sending itself
|
||
a VA_CAPACITY message with vastr.len as the size.
|
||
|
||
|
||
If there are no records in the array, the array cell is freed (as required by varoorT).
|
||
|
||
|
||
& VA_DELETEM Delete a sequence of records
|
||
|
||
|
||
VOID va_deletem(UINT num, UINT nrecs) ;
|
||
|
||
|
||
Delete the sequence of nrecs records, starting at record number nun, and decrease the value of
|
||
varoot.nrec by nrecs.
|
||
|
||
|
||
The deletion is performed by simply copying all following records over the records to be deleted. No
|
||
memory is freed.
|
||
|
||
|
||
Calls p_panic(P_PANIC_P_VASTR_4) if num+nrecs 1s greater than the number of records in the array.
|
||
|
||
|
||
VA_INSERTM Insert a sequence of records
|
||
|
||
|
||
VOID va_insertm(UINT num, VOID *prec, UINT nrecs);
|
||
|
||
|
||
Insert the sequence of nrecs records, pointed to by prec, before record number nun, and increase the value
|
||
of varoot .nrec by nrecs.
|
||
|
||
|
||
The valid range for num is from zero to the number of records inclusive.
|
||
|
||
|
||
In the record sequence at prec, each subsequent string should immediately follow the zero terminator of
|
||
the previous string.
|
||
|
||
|
||
Calls p_panic(P_PANIC_P_VASTR_3) if num is greater than the number of records in the array.
|
||
|
||
|
||
Inserts no records and calls p_leave (E_GEN_NOMEMoRY) if there is not enough memory available to hold all
|
||
the additional records.
|
||
|
||
|
||
& VA_RECLEN Get record length
|
||
|
||
|
||
UINT va_reclen(UINT num);
|
||
|
||
|
||
Return the record length of record number num. The returned length excludes the zero terminator.
|
||
|
||
|
||
& VA_PREC Point to record
|
||
VOID *va_prec(UINT num);
|
||
Return the address of record number num. The pointer returned is to a zero terminated string.
|
||
|
||
|
||
Calls p_panic(P_PANIC_P_VASTR_1) if num is greater than or equal to the number of records in the array.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
& VA_PBUF Point to record data
|
||
|
||
|
||
VOID *va_pbuf (UINT num)
|
||
|
||
|
||
AS VA_PREC.
|
||
|
||
|
||
& VA_COPY Copy a record
|
||
|
||
|
||
UINT va_copy(UINT num, VOID *prec);
|
||
|
||
|
||
Copy the record specified by the parameter num to the location pointed to by the parameter prec; by
|
||
sending itself a va_PREC message to convert recno into a record pointer and then using p_bcpy to copy
|
||
that record data from the array to prec.
|
||
|
||
|
||
Returns the length copied.
|
||
|
||
|
||
VAFLAT
|
||
|
||
|
||
VAROOT VAFIX
|
||
|
||
|
||
destroy va_replace va_init
|
||
va_count va_copy va_compress
|
||
va_delete va_reclen va_deletem
|
||
|
||
|
||
va_sort va_swap va_insertm
|
||
|
||
|
||
va_key va_capacity
|
||
|
||
|
||
va_findisgq ind va_prec
|
||
va_insertisq va_pbuf
|
||
va_append
|
||
|
||
va_insert
|
||
|
||
va_search
|
||
|
||
va_compare
|
||
|
||
va_reset
|
||
|
||
|
||
va_test
|
||
|
||
|
||
The variat class may be used to create arrays of fixed length records where the whole array is stored in a
|
||
single allocated cell. When a record is inserted into a full array, the single cell is reallocated to
|
||
accommodate the additional record. Deletions do not automatically reduce the record capacity but the
|
||
capacity may be reduced manually using va_compress Or va_capacity.
|
||
|
||
|
||
The vartat class is suitable for short arrays or for large arrays which have a known maximum capacity. It
|
||
is not suitable for arrays which can dynamically grow to a large size because heap fragmentation can
|
||
seriously reduce the effective use of heap memory.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file varray.cl (generated header file varray.g).
|
||
|
||
|
||
CLASS vaflat vafix
|
||
Flat allocated (in a single cell) fixed length variable arrays
|
||
{
|
||
REPLACE va_init
|
||
REPLACE va_compress
|
||
REPLACE va_deletem
|
||
REPLACE va_insertm
|
||
REPLACE va_capacity
|
||
REPLACE va_prec
|
||
REPLACE va_pbuf=vaflat_va_prec
|
||
|
||
|
||
PROPERTY
|
||
{
|
||
UWORD gran; granularity in records
|
||
UWORD nspc; present record capacity
|
||
|
||
|
||
UBYTE *base; start of variable array
|
||
}
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
Property
|
||
vaflat.gran The granularity, in records, in which to allocate memory. It should not be
|
||
accessed by any subclass.
|
||
vaflat.nspe The number of fixed sized record slots allocated (greater than or equal to
|
||
the number of records in the array). It should not be accessed by any
|
||
subclass.
|
||
vaflat.base The allocated space handle, i.e. the start of the variable array. It should
|
||
|
||
|
||
not be accessed by any subclass.
|
||
|
||
|
||
VAFLAT methods
|
||
© VA_INIT Initialise
|
||
|
||
|
||
VOID va_init (UINT reclen, UINT gran);
|
||
|
||
|
||
Initialise the array by setting vafix.rlen from reclen and vaflat.gran from gran. No capacity is
|
||
actually allocated until the first insertion, hence no errors can occur.
|
||
|
||
|
||
The granularity is significant when an insertion requires an increase in capacity; the increase is such that
|
||
the capacity, in records, is made an exact multiple of the granularity. Increasing the value of gran means
|
||
that the array cell needs to be reallocated less frequently (hence less heap fragmentation) as a result of
|
||
insertions, but more memory may be wasted in unused capacity. Any unused capacity may be recovered by
|
||
sending a vA_compREss message when the building of an array is complete.
|
||
|
||
|
||
VA_CAPACITY Set capacity
|
||
|
||
|
||
VOID va_capacity(UINT nspc);
|
||
|
||
|
||
Set the capacity of the array cell by reallocating it to have exactly the capacity for nspc records (i.e.
|
||
nspc*vafix.rlen bytes).
|
||
|
||
|
||
Does not alter the capacity and calls p_leave (E_GEN_NoMEMoRY) if there is not enough memory for the
|
||
specified capacity.
|
||
|
||
|
||
Calls p_panic (P_PANIC_P_VAFLAT_3) if nspc is less than the current number of records in the array.
|
||
|
||
|
||
& VA_COMPRESS Compress
|
||
|
||
|
||
VOID va_compress (VOID)
|
||
|
||
|
||
Compress the capacity of the array to exactly that required to hold the current records. This is achieved by
|
||
sending itself a va_capaciTy message to set the capacity to varoot .nrec records. If there are no records in
|
||
the array, the array cell is freed as required by the varoort class.
|
||
|
||
|
||
& VA_DELETEM Delete sequence of records
|
||
|
||
|
||
VOID va_deletem(UINT recno, UINT nrecs);
|
||
Delete the sequence of nrecs records starting at record recno.
|
||
|
||
|
||
Calls p_panic (P_PANIC_P_VAFLAT_4) if recnotnrecs is greater than the number of records in the array.
|
||
|
||
|
||
The number of records in the array, held in varoot .nrec, 1s reduced by nrecs. The delete is performed by
|
||
copying the data of following records over the records being deleted. No allocated space is freed.
|
||
|
||
|
||
VA_INSERTM Insert sequence of records
|
||
|
||
|
||
VOID va_insertm(UINT recno, VOID *prec, UINT nrecs)
|
||
|
||
|
||
Inserts the sequence of nrecs records pointed to by prec before record recno where recno is between zero
|
||
and the number of records inclusive.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
If the array cannot currently hold all the additional records, the record capacity is set (by sending itself a
|
||
VA_CAPACITY message) to the smallest exact multiple of the granularity that is greater than the total
|
||
number of records to be held. The data is inserted by opening up a gap in the array (by buffer copying)
|
||
then copying the new data into the gap.
|
||
|
||
|
||
Inserts no records and calls p_1eave (E_GEN_NOMEMOoRY) If there is not enough memory available to hold
|
||
the additional records.
|
||
|
||
|
||
Calls p_panic(P_PANIC_P_VAFLAT_2) if recno is greater than the number of records in the array.
|
||
|
||
|
||
& VA_PREC Point to record
|
||
|
||
|
||
VOID *va_prec(UINT recno)
|
||
Return the address of record recno.
|
||
|
||
|
||
Calls p_panic(P_PANIC_P_VAFLAT_1) if recno is greater than or equal to the number of records in the
|
||
array.
|
||
|
||
|
||
& VA_PBUF Point to record data
|
||
|
||
|
||
VOID *va_pbuf (UINT recno);
|
||
|
||
|
||
AS VA_PREC.
|
||
|
||
|
||
VASEG
|
||
|
||
|
||
VAROOT VAFIX
|
||
ae eet
|
||
|
||
|
||
destroy va_replace va_init
|
||
va_count va_copy va_compress
|
||
va_delete va_reclen va_deletem
|
||
|
||
|
||
va_sort va_swap va_insertm
|
||
|
||
|
||
va_key va_capacity
|
||
|
||
|
||
va_findisgq Het va_prec
|
||
va_insertisq va_pbuf
|
||
va_append
|
||
|
||
va_insert
|
||
|
||
va_search
|
||
|
||
va_compare
|
||
|
||
va_reset
|
||
|
||
|
||
va_test
|
||
|
||
|
||
The vassc class may be used to create arrays of fixed length records where the array is segmented into a
|
||
number of equal sized blocks. The segments are allocated from the heap and are doubly linked.
|
||
|
||
|
||
The segmented array object is suitable for large dynamically changing arrays and is substantially more
|
||
likely to make efficient use of the available heap memory. Its disadvantage is that it takes longer to locate
|
||
a random record by record number because it has to count through the segments. However, the object
|
||
remembers the last record accessed so that scanning a segmented array sequentially from the first record is
|
||
reasonably efficient.
|
||
|
||
|
||
The segments are generally not less than 50% full. See the scpur class documentation (in the SGBUF
|
||
Segmented Buffer Class chapter) for more information on the segmentation mechanisms.
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file varray.cl (generated header file varray.g).
|
||
|
||
|
||
CLASS vaseg vafix
|
||
Segmented fixed length variable arrays
|
||
{
|
||
REPLACE va_init
|
||
REPLACE va_compress
|
||
REPLACE va_capacity=p_dummy
|
||
REPLACE va_deletem
|
||
REPLACE va_insertm
|
||
REPLACE va_prec
|
||
REPLACE va_pbuf=vaseg_va_prec
|
||
|
||
|
||
PROPERTY 1
|
||
{
|
||
PR_SGBUF *buf; segmented buffer
|
||
}
|
||
}
|
||
Property
|
||
vaseg.buf The object handle of the owned instance of the segmented buffer (scpur)
|
||
|
||
|
||
class. This may be used by any subclass to access the scBur object.
|
||
|
||
|
||
VASEG methods
|
||
VA_INIT Initialise
|
||
|
||
|
||
VOID va_init (UINT rlen, UINT granularity);
|
||
|
||
|
||
Initialise the array by setting the record length to rien, creating a scBur object and initialising it with a
|
||
segment size of rlen*granularity. Note that, since the segment size is an exact multiple of the record
|
||
length, the content of a record will never straddle a segment boundary (significant for the va_prec and
|
||
va_pbuf methods).
|
||
|
||
|
||
The first segment is not allocated until the first insertion.
|
||
|
||
|
||
Calls p_leave (E_GEN_NoMEMoRyY) if it cannot create the scpur object.
|
||
|
||
|
||
VA_CAPACITY Set capacity
|
||
|
||
|
||
Setting the capacity does not make any sense for the vaseg class and this method does nothing.
|
||
|
||
|
||
& VA_COMPRESS Compress
|
||
|
||
|
||
VOID va_compress (VOID)
|
||
|
||
|
||
Compress the capacity of the array by sending an sB_comrEss message to the owned scBur object.
|
||
|
||
|
||
& VA_DELETEM Delete a sequence of records
|
||
|
||
|
||
VOID va_deletem(UINT recno, UINT nrecs);
|
||
|
||
|
||
Delete the sequence of nrecs records starting at record recno. The delete is performed by sending an
|
||
SB_DELETE message to the owned scBur object.
|
||
|
||
|
||
Reduces the record count by nrecs.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
VA_INSERTM
|
||
|
||
|
||
VOID va_insertm(UINT recno, VOID *prec, UINT nrecs) ;
|
||
|
||
|
||
Insert a sequence of records
|
||
|
||
|
||
Insert the sequence of nrecs records pointed to by prec before record recno, where recno is between zero
|
||
and the number of records inclusive. The insert is performed by sending an sB_INsERT message to the
|
||
owned scBur object.
|
||
|
||
|
||
Increases the record count by nrecs if the insertion was successful.
|
||
|
||
|
||
Inserts no records and calls p_leave (E_GEN_NOMEMoRY) if there is not enough memory available to hold
|
||
the additional records.
|
||
|
||
|
||
& VA_PREC Point to record
|
||
|
||
|
||
VOID *va_prec(UINT recno)
|
||
Returns the address of record number recno.
|
||
The record pointer is obtained by sending an sp_pornt message to the owned scBurF object.
|
||
|
||
|
||
Calls p_panic(P_PANIC_P_VASEG_1) if recno is greater than or equal to the number of records in the
|
||
array.
|
||
|
||
|
||
& VA_PBUF Point to record data
|
||
|
||
|
||
VOID *va_pbuf (UINT recno)
|
||
|
||
|
||
AS va_prec.
|
||
|
||
|
||
VAXVAR
|
||
|
||
|
||
VAROOT VAFIX VAFLAT
|
||
|
||
|
||
gran
|
||
|
||
|
||
nspc
|
||
|
||
|
||
destroy
|
||
va_count
|
||
va_delete
|
||
va_sort
|
||
|
||
|
||
va_key
|
||
|
||
|
||
va_findisgq
|
||
|
||
|
||
va_insertisq
|
||
va_append
|
||
va_insert
|
||
va_search
|
||
va_compare
|
||
va_reset
|
||
|
||
|
||
va_test
|
||
|
||
|
||
va_compress
|
||
|
||
|
||
ac4 tem
|
||
vFarinsertm
|
||
va_capacity
|
||
va_prec
|
||
|
||
|
||
vwarpbut
|
||
|
||
|
||
va_test
|
||
va_copy
|
||
va_reclen
|
||
va_replace
|
||
va_init
|
||
va_deletem
|
||
va_insertm
|
||
|
||
|
||
va_pbuf
|
||
|
||
|
||
The vaxvar class may be used to create arrays of variable length records where there is no restriction on
|
||
the values of the bytes which can be stored within records. Each record is stored in its own heap cell and
|
||
the records are indexed by a variat array of Rc_vAxvaR structs.
|
||
|
||
|
||
The vaxvar class subclasses the fixed length record array vartat which provides its index. Although
|
||
vaxvar has variable length records, only 8 of the methods inherited from variat needed to be replaced.
|
||
|
||
|
||
In vaxvar, records are not described simply by their address but indirectly via the address of a record
|
||
descriptor. A record descriptor is a RC_vaxvar struct that contains the address and length of a record.
|
||
|
||
|
||
The rc_vaxvar struct is used to specify records both outside and inside the array. For example, the
|
||
insertion methods va_append, va_insert, va_insertisg and va_insertm all require the address of an
|
||
RC_VAXVAR Struct - and the va_prec method returns the address of an rc_vaxvar struct.
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
The va_pbuf method will return a pointer to the actual data buffer (ie the Rc_vaxvar buf field). The
|
||
va_copy method takes a buffer address (to take the copied record) rather than the address of an Rc_vaxvarR
|
||
struct.
|
||
|
||
|
||
When a record is inserted, a cell is allocated for the variable length record data and an index record is
|
||
inserted - the capacity of the index may need to be increased. When a record is deleted, the record data
|
||
cell is freed and the corresponding index record is deleted. Deletions do not automatically reduce the
|
||
record capacity of the index but the index capacity may be reduced manually using va_compress or
|
||
va_capacity. There is no means of controlling the capacity of the record data storage.
|
||
|
||
|
||
On a 16-bit address machine, the overhead per record is 4 bytes for the Rc_vaxvar record and at least 2
|
||
bytes for the allocated cell. However, any zero length records do not have an associated record value cell
|
||
and, in this case, the corresponding but (address) field of the rc_vaxvar struct is guaranteed to be nuLL.
|
||
|
||
|
||
The vaxvar class is suitable for short to medium length arrays or for large arrays which have a known
|
||
maximum capacity (in terms of the number of records required). It is not suitable for arrays which can
|
||
dynamically grow to a large number of records because the index is in a single cell. The vaxvars class
|
||
(which has a segmented index) should be used when there is a possibility of growth to a large number of
|
||
records.
|
||
|
||
|
||
Compared to vastr, vaxvar has the following advantages:
|
||
® vaxvar can store arbitrary record data, which may include zero bytes
|
||
e random access to vaxvar records is efficient
|
||
|
||
|
||
@ vaxvar records may be exchanged efficiently since only the corresponding index items are
|
||
exchanged - the sort method is thus very efficient
|
||
|
||
|
||
e the data for each record is stored in a separately allocated cell, so heap fragmentation is less
|
||
likely to be a problem
|
||
|
||
|
||
Compared to vastr, vaxvar has the following disadvantages:
|
||
e the record overhead in vaxvar is at least six bytes compared to one byte in vasTR
|
||
|
||
|
||
e the Rc_vaxvar descriptor which is used to describe a record is often less convenient than the
|
||
address of a zero terminated string, but the va_pbuf method overcomes this quite well
|
||
|
||
|
||
e —vaxvar records do not automatically provide a zero terminator
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file varray.cl (generated header file varray.g).
|
||
|
||
|
||
CLASS vaxvar vaflat
|
||
Indexed variable length record variable arrays - one record per heap cell
|
||
{
|
||
REPLACE va_test
|
||
REPLACE va_copy
|
||
REPLACE va_reclen
|
||
REPLACE va_replace
|
||
REPLACE va_init
|
||
REPLACE va_deletem
|
||
REPLACE va_insertm
|
||
REPLACE va_pbuf
|
||
TYPES
|
||
{
|
||
typedef struct
|
||
{
|
||
UWORD len; record length
|
||
UBYTE *buf; record data
|
||
} RC_VAXVAR;
|
||
|
||
|
||
}
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
VAXVAR methods
|
||
|
||
|
||
& VA_INIT Initialise
|
||
|
||
|
||
VOID va_init (UINT gran) ;
|
||
|
||
|
||
Initialise the array by supersending the va_1n1T message to the varLat object, passing the size of an
|
||
RC_VAxvaR Structure as the record size and gran as the granularity. The subclassed variat array provides
|
||
the index used by the vaxvar object. No capacity is actually allocated until the first insertion, hence no out
|
||
of memory errors can occur.
|
||
|
||
|
||
The granularity is significant when an insertion requires an increase in capacity; the increase is such that
|
||
the capacity, in records, is made an exact multiple of the granularity. Making this value larger means that
|
||
the index array cell needs to be reallocated less frequently (hence less heap fragmentation) as a result of
|
||
insertions, but more memory may be wasted in unused capacity.
|
||
|
||
|
||
& VA_TEST Compare two records by pointer
|
||
|
||
|
||
INT va_test (VOID *precl, VOID *prec2);
|
||
|
||
|
||
Compare the record pointed to by prec2->buf with the record at prec1->buf, on the assumption that they
|
||
contain text, exactly as for the vaRooT va_test method.
|
||
|
||
|
||
The basis for the comparison is subject to the contents of varoot .key, set by va_key, as follows:
|
||
|
||
|
||
if varoot .key.1len==0 it uses
|
||
p_scmp df varoot.key.fold is FALSE), or
|
||
p_scmpi af varoot.key.fold is TRUE).
|
||
|
||
|
||
if varoot .key.len>0 it uses
|
||
p_bemp (if varoot.key.fold iS FALSE), OF
|
||
p_bcempi af varoot.key.fold is TRUE).
|
||
|
||
|
||
The default is to use p_scmp.
|
||
|
||
|
||
Returns the logical equivalent of (*preci1->buf-*prec2->buf) - that is, zero if the two records are equal,
|
||
negative if *preci->buf is before (less than) *prec2->buf, positive if after. If key. desc iS TRUE this result
|
||
is reversed.
|
||
|
||
|
||
& VA_DELETEM Delete a sequence of records
|
||
|
||
|
||
VOID va_deletem(UINT recno, UINT nrecs);
|
||
Delete the sequence of nrecs records starting at record recno.
|
||
|
||
|
||
The process of deletion is two fold: first, the records defined by the rc_vaxvar elements are found and any
|
||
allocated cell (buffer data) is freed; Second, the index elements are deleted by supersending a va_DELETEM
|
||
message.
|
||
|
||
|
||
VA_INSERTM Insert a sequence of records
|
||
|
||
|
||
VOID va_insertm(UINT recno, RC_VAXVAR *prec, UINT nrecs);
|
||
|
||
|
||
Insert the sequence of nrecs records pointed to by prec before record recno, where recno is between zero
|
||
and the number of records inclusive. The record sequence pointed to by prec must be a contiguous array
|
||
of nrecs RC_VAXVAR Structs.
|
||
|
||
|
||
The insertion of records is a two stage process. Firstly the index entries are inserted by supersending a
|
||
VA_INSERTM message to the varLat superclass. If this is successful, a heap cell is allocated for each record
|
||
to be inserted, the data is copied into each cell and the cell handle written to the rc_vaxvar buf field. If an
|
||
allocation fails, all entries made so far are removed, their allocated cells being freed.
|
||
|
||
|
||
Inserts no records and calls p_leave (E_GEN_NOMEMoRY) if there is not enough memory available to hold all
|
||
the additional records.
|
||
|
||
|
||
5 VARIABLE ARRAY CLASSES
|
||
|
||
|
||
VA_REPLACE
|
||
|
||
|
||
VOID va_replace(UINT recno, RC_VAXVAR *prec);
|
||
|
||
|
||
Replace record
|
||
|
||
|
||
Replace record recno with the record described by the rc_vaxvar struct at prec, by freeing the original
|
||
record cell, allocating a new cell of the appropriate size and replacing the index record with the new
|
||
descriptor.
|
||
|
||
|
||
Calls p_leave (E_GEN_NOMEMoRY) , Without modifying the original record, if there is not enough memory
|
||
available to hold the replacement record.
|
||
|
||
|
||
& VA_COPY Copy a record
|
||
|
||
|
||
UINT va_copy(UINT recno, VOID *pbuf);
|
||
|
||
|
||
Copy record number recno by supersending itself a va_copy message to get the record descriptor and then
|
||
using p_bcpy to copy the record data to pbuf.
|
||
|
||
|
||
Returns the length of the data copied to pbut.
|
||
|
||
|
||
& VA_RECLEN
|
||
|
||
|
||
UINT va_reclen(UINT recno);
|
||
|
||
|
||
Get record length
|
||
|
||
|
||
Returns the record length of record recno.
|
||
|
||
|
||
& VA_PBUF Point to record data
|
||
|
||
|
||
VOID *va_pbuf (UINT recno);
|
||
Returns a pointer to the record data, read from the bur field of the corresponding Rc_vaxvar struct.
|
||
|
||
|
||
It should be noted that the va_prec method (provided by the variart superclass) returns a pointer to the
|
||
RC_VAXVAR Struct.
|
||
|
||
|
||
VAXVARS
|
||
|
||
|
||
VAROOT VAFIX VASEG VAXVARS
|
||
|
||
|
||
nrec ke
|
||
|
||
|
||
destroy ad va_test
|
||
|
||
|
||
va_count
|
||
va_delete
|
||
va_sort
|
||
|
||
|
||
va_key
|
||
|
||
|
||
va_findisgq
|
||
|
||
|
||
va_insertisq
|
||
va_append
|
||
va_insert
|
||
va_search
|
||
va_compare
|
||
va_reset
|
||
|
||
|
||
va_test
|
||
|
||
|
||
va_compress
|
||
|
||
|
||
a ee
|
||
Farinsertm
|
||
va_capacity
|
||
va_prec
|
||
|
||
|
||
wa pbut
|
||
|
||
|
||
va_copy
|
||
va_reclen
|
||
va_replace
|
||
va_init
|
||
va_deletem
|
||
va_insertm
|
||
|
||
|
||
va_pbuf
|
||
|
||
|
||
The vaxvars class is identical to the vaxvar class except that it subclasses the vaszc class (a segmented
|
||
array) for its index rather than var.at (a flat array). In other words, the index records are placed in a
|
||
|
||
|
||
segmented buffer.
|
||
|
||
|
||
The vaxvars class should be used in preference to vaxvar when there is the possibility of a large number
|
||
|
||
|
||
of records.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file varray.cl (generated header file varray.g).
|
||
|
||
|
||
CLASS vaxvars vaseg
|
||
Indexed variable length record variable arrays - one record per heap cell
|
||
Uses a segmented array for an index
|
||
|
||
|
||
REPLACE va_test=vaxvar_va_test
|
||
REPLACE va_copy=vaxvar_va_copy
|
||
REPLACE va_reclen=vaxvar_va_reclen
|
||
REPLACE va_replace=vaxvar_va_replace
|
||
REPLACE va_init=vaxvar_va_init
|
||
REPLACE va_deletem=vaxvar_va_deletem
|
||
REPLACE va_insertm=vaxvar_va_insertm
|
||
REPLACE va_pbuf=vaxvar_va_pbuf
|
||
|
||
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
VAXVARS methods
|
||
|
||
|
||
See VAXVAR methods.
|
||
|
||
|
||
CHAPTER 6
|
||
|
||
|
||
EDITABLE DOCUMENTS
|
||
|
||
|
||
The EPROOT, EPFLAT and EpsEc classes provide the means of storing, reading and editing, in memory, the
|
||
text of a document. The text must always have a terminating zero but may otherwise be of any length up
|
||
to a maximum of 65535 characters, subject to memory constraints.
|
||
|
||
|
||
The methods support the use of an instance of (a subclass of) EPFLAT or EPSEG as a clipboard. Text may be
|
||
cut or copied into such a clipboard from a document or pasted from a clipboard into a document.
|
||
|
||
|
||
Document content
|
||
The concepts of words, paragraphs and blocks are built into the document content model, where:
|
||
|
||
|
||
e® a paragraph is any sequence of characters delimited by a paragraph delimiter. A paragraph
|
||
delimiter is an ASCII 0, 1, 2 or 3, a value of 0 being by far the most commonly used. The final
|
||
paragraph delimiter in the document is always an ASCII zero.
|
||
|
||
|
||
e aword is any sequence of characters delimited by one or more word delimiter characters. A word
|
||
delimiter is either a paragraph delimiter, or a whitespace character (for which p_isspace returns
|
||
TRUE).
|
||
|
||
|
||
e a block is a sequence of paragraphs delimited by paragraphs that are either empty or, if not
|
||
empty, contain only whitespace characters.
|
||
|
||
|
||
The terminating ASCII zero is generally not regarded as part of the editable content. It is not, for
|
||
example, included in the document length as returned by an ep_sense_len method.
|
||
|
||
|
||
Its presence is fundamental to the operation of all classes that subclass EPRoot and it should never be
|
||
deleted.
|
||
|
||
|
||
Addressable character positions
|
||
|
||
|
||
A position in an EPFLAT or EPSEG document is considered, in general, to mark the point between two
|
||
adjacent characters. Thus, character position 3 is interpreted as being between the third and fourth
|
||
characters. Character position zero is before the first character in the document.
|
||
|
||
|
||
Inserting at position 9, say, will insert text after the ninth character: deleting the characters between
|
||
positions 3 and 5 will delete the fourth and fifth characters.
|
||
|
||
|
||
The last addressable character position is immediately before the final paragraph delimiter (always an
|
||
ASCII zero).
|
||
|
||
|
||
Usage
|
||
|
||
|
||
Instances of (subclasses of) EPFLAT and EPsEc are widely used in all SIBO machines to contain editable
|
||
text. Examples range from the text in a dialog edit box, to the text of a word processor document.
|
||
|
||
|
||
In general, The epriat class should be used for small amounts of text, or for documents with a limited
|
||
variability of content, whereas the EpsEc class should be used for larger documents, or for those with a
|
||
wide dynamic content range. (Compare this with the recommended use of the varLat and vaszc variable
|
||
array classes.)
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
An understanding of the following topics would prove helpful:
|
||
e =the p_enter and p_leave error handling services
|
||
|
||
|
||
e for EPsEG, the scpur segmented buffer class
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
fees
|
||
|
||
|
||
¢ eproot /
|
||
|
||
|
||
~ S22)
|
||
|
||
~
|
||
COS. pee fB
|
||
¢ epflat / ~ epseg y y sgbuf /
|
||
> js 4.43 es )
|
||
|
||
|
||
Na ae Los
|
||
|
||
|
||
Sees
|
||
|
||
|
||
—
|
||
|
||
|
||
EPROOT
|
||
|
||
|
||
ep_set_text ep_sense_text
|
||
ep_scan_word ep_capacity
|
||
ep_word_count
|
||
|
||
|
||
ep_scan_para ep_compress
|
||
|
||
|
||
ep_para_count ep_init
|
||
|
||
|
||
ep_scan_block ep_sense_len
|
||
ep_add_para ep_sense_chars
|
||
ep_copy_indent ep_back_chars
|
||
ep_copy_to_front ep_insert
|
||
ep_copy_to_back ep_delete
|
||
ep_paste ep_extract
|
||
ep_mod_chars ep_clear
|
||
|
||
|
||
The Eproot abstract class provides the basic methods for manipulating the text of a document.
|
||
|
||
|
||
6 EDITABLE DOCUMENTS
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file edit.cl (generated header file edit. g).
|
||
|
||
|
||
CLASS eproot root
|
||
|
||
|
||
Editable paragraphs (abstract class)
|
||
|
||
{
|
||
|
||
ADD ep_set_text Set the contents, replacing any previous contents
|
||
|
||
ADD ep_scan_word Scan by words
|
||
|
||
ADD ep_word_count Return word count
|
||
|
||
ADD ep_scan_para Scan by paragraphs
|
||
|
||
ADD ep_para_count Return paragraph count
|
||
|
||
ADD ep_scan_block Scan by blocks
|
||
|
||
ADD ep_add_para Append a paragraph given its content
|
||
|
||
ADD ep_copy_indent Copy indent from previous paragraph
|
||
|
||
ADD ep_copy_to_front Copy range to front of provided clipboard
|
||
|
||
ADD ep_copy_to_back Copy range to back of provided clipboard
|
||
|
||
ADD ep_paste Paste from provided clipboard, update position
|
||
|
||
ADD ep_mod_chars Various mods to a range of characters
|
||
|
||
ADD ep_sense_text Copy out all the data and return its length
|
||
|
||
ADD ep_capacity=p_dummy Adjust storage to stated capacity
|
||
|
||
DEFER ep_compress Compress storage to minimum possible
|
||
|
||
DEFER ep_init Prepare an empty editable object
|
||
|
||
DEFER ep_sense_len Return length of data
|
||
|
||
DEFER ep_sense_chars Provide pointer to following contiguous data
|
||
|
||
DEFER ep_back_chars Provide pointer to previous contiguous data
|
||
|
||
DEFER ep_insert Insert block of characters
|
||
|
||
DEFER ep_delete Delete range of text
|
||
|
||
DEFER ep_extract Extract data into buffer
|
||
|
||
DEFER ep_clear Empty the object of all contents
|
||
|
||
CONSTANTS
|
||
{
|
||
EP_SCAN_BACKWARDS Ox01 Scan backwards if set
|
||
EP_SCAN_STAY 0x02 Will stay put if already at a boundary
|
||
EP_SCAN_TO_BEGIN 0x04 Stops at beginning of unit
|
||
EP_SCAN_TO_END 0x08 Stops at end of unit
|
||
EP_SCAN_JOIN_DELIM 0x10 Sequence of delimiters count as one
|
||
EP_SCAN_NOT_TO_END 0x20 Do not scan past the final terminator
|
||
EP_RETURN_LENGTH -1 special meaning for ep_sense_chars
|
||
EP_MOD_TOLOWER 0 fold to lower case
|
||
EP_MOD_TOUPPER 1 fold to upper case
|
||
EP_MOD_WRAP 2 join paragraphs by converting zeros to spaces
|
||
}
|
||
|
||
PROPERTY
|
||
{
|
||
UWORD maxlen; Maximum permissible length of text
|
||
}
|
||
|
||
}
|
||
|
||
Property
|
||
eproot.maxlen the maximum permissible length of the text. All subclasses must set this
|
||
|
||
|
||
field, normally in an ep_init method
|
||
|
||
|
||
EPROOT methods
|
||
EP_SET TEXT Set content
|
||
|
||
|
||
VOID ep_set_text (TEXT *buf, UINT len);
|
||
|
||
|
||
Replace any existing text with a single paragraph containing 1en characters copied from *buf. The value
|
||
of 1en should exclude any trailing paragraph terminator.
|
||
|
||
|
||
Calls p_1eave for out of memory errors. In this event, none of the existing text will have been replaced.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
& EP_SCAN_ WORD
|
||
|
||
|
||
Scan by word
|
||
|
||
|
||
UINT ep_scan_word(UWORD *ppos, UINT flags);
|
||
|
||
|
||
Scan, from character position *ppos, by one word, updating *ppos to the new character position and
|
||
returning the number of characters skipped by the scan. There is no need for the initial position to be at a
|
||
|
||
|
||
word boundary.
|
||
|
||
|
||
The value of f1ags may be any combination of the following:
|
||
|
||
|
||
EP_SCAN_BACKWARDS
|
||
|
||
|
||
EP_SCAN_STAY
|
||
|
||
|
||
EP_SCAN_TO_BEGIN
|
||
|
||
|
||
EP_SCAN_TO_END
|
||
|
||
|
||
EP_SCAN_JOIN_DELIM
|
||
|
||
|
||
EP_SCAN_NOT_TO_END
|
||
|
||
|
||
Scan backwards if set, otherwise scan forwards
|
||
|
||
Do not scan if already at a word boundary
|
||
|
||
Scan to the beginning of a word
|
||
|
||
Scan to the end of a word
|
||
|
||
Treat a sequence of word delimiters as a single delimiter
|
||
|
||
|
||
Do not scan past the final terminator
|
||
|
||
|
||
& EP_WORD COUNT
|
||
|
||
|
||
UINT ep_word_count (VOID) ;
|
||
|
||
|
||
Count words
|
||
|
||
|
||
Return a count of the total number of words in the document.
|
||
|
||
|
||
& EP_SCAN_PARA
|
||
|
||
|
||
UINT ep_scan_para(UWORD *ppos, UINT flags);
|
||
|
||
|
||
Scan by paragraph
|
||
|
||
|
||
Scan, from character position *ppos, by one paragraph, updating *ppos to the new character position and
|
||
returning the number of characters skipped by the scan. There is no need for the initial position to be at a
|
||
paragraph boundary.
|
||
|
||
The value of f1ags may be any combination of the following:
|
||
|
||
EP_SCAN_BACKWARDS Scan backwards if set, otherwise scan forwards
|
||
EP_SCAN_STAY Do not scan if already at a paragraph boundary
|
||
EP_SCAN_TO_BEGIN Scan to the beginning of a paragraph
|
||
EP_SCAN_TO_END Scan to the end of a paragraph
|
||
EP_SCAN_JOIN_DELIM Treat a sequence of paragraph delimiters as a single delimiter
|
||
|
||
|
||
EP_SCAN_NOT_TO_END Do not scan past the final terminator
|
||
|
||
|
||
& EP_PARA_COUNT
|
||
|
||
|
||
UINT ep_para_count (VOID) ;
|
||
|
||
|
||
Count paragraphs
|
||
|
||
|
||
Return a count of the total number of paragraphs in the document.
|
||
|
||
|
||
© EP_SCAN BLOCK
|
||
|
||
|
||
UINT ep_scan_block(UWORD *ppos, UINT flags);
|
||
|
||
|
||
Scan by block
|
||
|
||
|
||
Scan, from character position *ppos, by one block, updating *ppos to the new character position and
|
||
returning the number of characters skipped by the scan.
|
||
|
||
|
||
The initial position is assumed to be at a paragraph boundary.
|
||
|
||
|
||
6 EDITABLE DOCUMENTS
|
||
|
||
|
||
The value of f1ags may be any combination of the following:
|
||
|
||
|
||
EP_SCAN_BACKWARDS Scan backwards if set, otherwise scan forwards
|
||
EP_SCAN_STAY Do not scan if already at a block boundary
|
||
EP_SCAN_TO_BEGIN Scan to the beginning of a block
|
||
|
||
EP_SCAN_TO_END Scan to the end of a block
|
||
|
||
EP_SCAN_JOIN_DELIM Treat a sequence of block delimiters as a single delimiter
|
||
EP_SCAN_NOT_TO_END Do not scan past the final terminator
|
||
|
||
|
||
EP_ADD_PARA Append a paragraph
|
||
|
||
|
||
VOID ep_add_para(TEXT *buf, UINT len);
|
||
Append a paragraph containing 1en bytes of text copied from *buf.
|
||
|
||
|
||
The text in buf is appended more efficiently if it is supplied as a zero terminated string - when len
|
||
should be equal to p_sien (buf) - but the terminating zero is not mandatory.
|
||
|
||
|
||
Calls p_leave, without inserting anything, if there is insufficient memory available to append the
|
||
|
||
|
||
paragraph.
|
||
|
||
|
||
EP_COPY_INDENT Copy whitespace indentation
|
||
|
||
|
||
UINT ep_copy_indent (UWORD *ppos) ;
|
||
|
||
|
||
Copy any leading whitespace from the previous paragraph (which is assumed to exist) to the character
|
||
position indicated by *ppos. This position will normally be the start of a paragraph.
|
||
|
||
|
||
The value of *ppos is incremented by the number of characters inserted.
|
||
Returns the number of characters inserted.
|
||
Inserts nothing and calls p_1eave if there is insufficient memory to perform the insertion.
|
||
|
||
|
||
Returns zero if the insertion is successful. The method is suitable for being called under the protection of
|
||
p_enter.
|
||
|
||
|
||
EP_COPY_TO_FRONT Copy range to front of clipboard
|
||
|
||
|
||
INT ep_copy_to_front (UINT posl, UINT pos2, PR_ROOT *clip);
|
||
|
||
|
||
Copy the range of characters between positions posi and posz2 to the front (position zero) of the clipboard
|
||
clip, where clip is assumed to be the handle of an instance of (a subclass of) EPROOT Or EPSEG.
|
||
|
||
|
||
Inserts nothing in the clipboard and calls p_ieave if there is insufficient memory to perform the insertion.
|
||
|
||
|
||
Returns zero if the insertion is successful. The method is suitable for being called under the protection of
|
||
p_enter.
|
||
|
||
|
||
EP_COPY_TO BACK Copy range to back of clipboard
|
||
|
||
|
||
INT ep_copy_to_back(UINT posl, UINT pos2, PR_ROOT *clip);
|
||
|
||
|
||
Copy the range of characters between positions posi and pos2 to the back (before the terminating zero) of
|
||
the clipboard clip, where clip is assumed to be the handle of an instance of (a subclass of) EPRooT or
|
||
EPSEG.
|
||
|
||
|
||
Inserts nothing in the clipboard and calls p_ieave if there is insufficient memory to perform the insertion.
|
||
|
||
|
||
Returns zero if the insertion is successful. The method is suitable for being called under the protection of
|
||
p_enter.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
EP_PASTE Insert from clipboard
|
||
|
||
|
||
INT ep_paste(UWORD *ppos, PR_EPROOT *clip);
|
||
|
||
|
||
Insert the contents of the clipboard clip, assumed to be the handle of an instance of (a subclass of) EPROOT
|
||
Of EPSEG, at position *ppos. The value of *ppos is updated to the end of the inserted text.
|
||
|
||
|
||
Inserts nothing and calls p_ieave if there is insufficient memory to perform the insertion.
|
||
|
||
|
||
Returns zero if the insertion is successful. The method is suitable for being called under the protection of
|
||
|
||
|
||
p_enter.
|
||
|
||
|
||
& EP_MOD_CHARS Modify characters in a range
|
||
|
||
|
||
VOID ep_mod_chars(UINT posl, UINT pos2, UINT mod);
|
||
|
||
|
||
Modify the characters between positions pos1 and pos2. The modification depends on the value of moa,
|
||
which may be one of:
|
||
|
||
|
||
EP_MOD_TOUPPER convert characters to upper case, with p_toupper
|
||
EP_MOD_TOLOWER convert characters to lower case, with p_tolower
|
||
EP_MOD_WRAP convert each paragraph delimiter character to a space (ASCII 32) character
|
||
|
||
|
||
& EP_SENSE TEXT Copy text to buffer
|
||
|
||
|
||
UINT ep_sense_text (TEXT *buf);
|
||
|
||
|
||
Copy the entire text of the document, including the terminating zero, to *buf. It is the user's responsibility
|
||
to ensure that the buffer is of sufficient length.
|
||
|
||
|
||
Returns the number of characters copied, excluding the terminating zero.
|
||
|
||
|
||
& EP_CAPACITY Set document capacity
|
||
|
||
|
||
VOID ep_capacity(UINT len);
|
||
|
||
|
||
This method does nothing, which is the appropriate action for subclasses using segmented storage (that is,
|
||
EPSEG or a subclass of EPSEG).
|
||
|
||
|
||
Subclasses using storage in a single allocated segment should subclass this method (see, for example,
|
||
EPFLAT'S ep_capacity method).
|
||
|
||
|
||
Deferred EPROOT methods
|
||
|
||
|
||
The deferred methods, listed below, are all fully described in the following documentation of the EPFLAT
|
||
and Epssc Classes.
|
||
|
||
|
||
EP_INIT Initialise
|
||
|
||
EP_SENSE_LEN Sense document length
|
||
EP_SENSE_CHARS Sense characters forwards
|
||
EP_BACK_CHARS Sense characters backwards
|
||
EP_INSERT Insert characters
|
||
EP_EXTRACT Copy out characters
|
||
EP_DELETE Delete characters
|
||
|
||
EP_CLEAR Clear the document
|
||
EP_COMPRESS Compress allocated storage
|
||
|
||
|
||
EPFLAT
|
||
|
||
|
||
maxlen
|
||
|
||
|
||
ep_set_text ep_sense_text
|
||
ep_scan_word
|
||
ep_word_count
|
||
ep_scan_para
|
||
ep_para_count
|
||
ep_scan_block
|
||
ep_add_para
|
||
ep_copy_indent
|
||
ep_copy_to_front
|
||
ep_copy_to_back
|
||
ep_paste
|
||
ep_mod_chars
|
||
|
||
|
||
EPFLAT stores the document text contiguously in a single allocated cell.
|
||
|
||
|
||
EPFLAT
|
||
|
||
|
||
destroy
|
||
ef_granularity
|
||
ef_sense_buf
|
||
ep_init
|
||
ep_sense_len
|
||
ep_sense_chars
|
||
ep_back_chars
|
||
ep_insert
|
||
ep_extract
|
||
ep_delete
|
||
ep_clear
|
||
ep_compress
|
||
ep_capacity
|
||
|
||
|
||
6 EDITABLE DOCUMENTS
|
||
|
||
|
||
This class is intended for use either to store relatively small amounts of text, or where the dynamic range
|
||
|
||
|
||
of the document size is small.
|
||
|
||
|
||
A typical example is to store the text of a dialog edit box.
|
||
Class definition
|
||
Defined in sub-category file edit.cl (generated header file edit. g).
|
||
|
||
|
||
CLASS epflat eproot
|
||
Editable paragraphs - stored in a single allocated cell
|
||
|
||
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
REPLACE
|
||
ADD ef_g
|
||
ADD ef_s
|
||
|
||
|
||
PROPERTY
|
||
{
|
||
UWOR
|
||
UWOR
|
||
UWOR
|
||
TEXT
|
||
}
|
||
|
||
}
|
||
|
||
|
||
Property
|
||
epflat.alen
|
||
|
||
|
||
epflat.gran
|
||
|
||
|
||
epflat.len
|
||
|
||
|
||
epflat.buf
|
||
|
||
|
||
destroy
|
||
ep_init
|
||
ep_sense_len
|
||
ep_sense_chars
|
||
ep_back_chars
|
||
ep_insert
|
||
ep_extract
|
||
ep_delete
|
||
ep_clear
|
||
ep_compress
|
||
ep_capacity
|
||
ranularity
|
||
ense_buf
|
||
|
||
|
||
Overwrite the default granularity
|
||
More convenient than ep_sense_chars
|
||
|
||
|
||
D alen;
|
||
D gran;
|
||
D len;
|
||
|
||
*buf;
|
||
|
||
|
||
length of allocated cell
|
||
granularity to grow by
|
||
length of text stored
|
||
address of text buffer
|
||
|
||
|
||
the size, in bytes, of the allocated cell. This should not be accessed by a subclass.
|
||
|
||
|
||
the granularity, in bytes. The allocated cell is grown, when necessary, in
|
||
multiples of this value. This should not be accessed by a subclass.
|
||
|
||
|
||
the number of bytes of stored text. This should be treated as a read-only field by a
|
||
subclass.
|
||
|
||
|
||
a pointer to the start of the buffer containing the text. This should be treated as a
|
||
read-only field by a subclass.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
EPFLAT methods
|
||
& DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID) ;
|
||
|
||
|
||
Free the allocated buffer and supersend the pestroy message.
|
||
|
||
|
||
EP_INIT Initialise
|
||
|
||
|
||
VOID ep_init (UINT maxlen) ;
|
||
|
||
|
||
Initialise the instance of EPpFLat to be suitable to contain up to maxlen bytes of text (typically the text will
|
||
not exceed that which can be displayed on a single line).
|
||
|
||
|
||
Sets eproot .maxlen tO maxlen and epflat.gran to a default value of eight bytes. Allocates a minimum
|
||
size buffer and inserts a single nun character.
|
||
|
||
|
||
Calls p_leave if there is insufficient memory to allocate the buffer.
|
||
|
||
|
||
& EP_SENSE LEN Sense document length
|
||
|
||
|
||
INT ep_sense_len (VOID) ;
|
||
|
||
|
||
Returns the number of characters in the document, excluding the terminating zero.
|
||
|
||
|
||
& EP_ SENSE CHARS Sense characters forwards
|
||
|
||
|
||
UINT ep_sense_chars (TEXT **pbuf, UINT pos, UINT n);
|
||
Write, to *pbuf, the address of the character at position pos.
|
||
|
||
|
||
Returns the smaller of n and the number of contiguously stored characters at *pbuf, including the zero
|
||
that terminates the document.
|
||
|
||
|
||
Note that for compatibility with the zpszc class, the interface to this method does not assume that the
|
||
entire text of the document is stored contiguously.
|
||
|
||
|
||
& EP_BACK_CHARS Sense characters backwards
|
||
|
||
|
||
UINT ep_back_chars (TEXT **pbuf, UINT pos, UINT n);
|
||
|
||
|
||
Write, to *pbuf, the address of the character whose position is n characters in front of position pos; if n is
|
||
greater than the number of characters in front of position pos, the address of the first character is taken.
|
||
|
||
|
||
Returns the number of contiguous characters at *pbuf up to, but not including, the character at position
|
||
pos. This value will not exceed n.
|
||
|
||
|
||
Note that, for compatibility with the Epszc class, the interface to this method does not assume that the
|
||
entire text of the document is stored contiguously.
|
||
|
||
|
||
EP_INSERT Insert characters
|
||
|
||
|
||
INT ep_insert (UINT pos, TEXT *buf, UINT len);
|
||
Insert 1en characters from *buf, at character position pos.
|
||
|
||
|
||
If pos is -1, the characters are inserted at the end of the document (before the terminating zero). This
|
||
feature is not replicated in the ep_insert method of the epsse class.
|
||
|
||
|
||
Inserts nothing and calls p_ieave if there is insufficient memory to perform the insertion (with an
|
||
E_GEN_NOMEMoRY error) or if the resulting document length were to exceed eproot .maxlen (with an
|
||
E_GEN_OVER error).
|
||
|
||
|
||
Returns zero if the insertion is successful. The method is suitable for being called under the protection of
|
||
p_enter.
|
||
|
||
|
||
6 EDITABLE DOCUMENTS
|
||
|
||
|
||
& EP_EXTRACT Copy out characters
|
||
|
||
|
||
VOID ep_extract (UINT pos, TEXT *buf, UINT len);
|
||
Copy len characters to *buf, starting with the character at position pos.
|
||
The user is responsible for ensuring that the buffer is of sufficient length to contain the text.
|
||
|
||
|
||
Note that no check is made to ensure that 1en characters are available at position pos.
|
||
|
||
|
||
& EP_DELETE Delete characters
|
||
|
||
|
||
VOID ep_delete(UINT posl, UINT pos2);
|
||
|
||
|
||
Delete the characters between positions pos1 and pos2, without making any attempt to reduce the size of
|
||
the allocated buffer.
|
||
|
||
|
||
If pos2 is -1 then all characters between position pos1 and the end of the document are cleared.
|
||
|
||
|
||
If pos2 is less than or equal to pos1 then the method does nothing.
|
||
|
||
|
||
& EP_CLEAR Clear the document
|
||
|
||
|
||
VOID ep_clear (VOID) ;
|
||
Remove any text. This leaves a document containing a single terminating zero.
|
||
|
||
|
||
No attempt is made to reduce the size of the allocated buffer.
|
||
|
||
|
||
EP_COMPRESS Compress allocated storage
|
||
|
||
|
||
VOID ep_compress (VOID) ;
|
||
|
||
|
||
Reduce the size of the allocated cell to the minimum required to contain the document, subject to the
|
||
restraint of the current value of epflat.gran. The cell will never be smaller than epfiat.gran bytes in
|
||
length.
|
||
|
||
|
||
This method can only fail (by calling p_1eave) if it follows an ErF_GRANULARITY message that alters the
|
||
granularity such that the ep_compress method causes the allocated cell to increase in size. In general (and
|
||
certainly if the ef_granularity method is never called) it is safe to assume that this method will never
|
||
fail.
|
||
|
||
|
||
EP_CAPACITY Set document capacity
|
||
|
||
|
||
VOID ep_capacity(UINT len);
|
||
Set the document capacity (using £_realloc) to 1en bytes, rounded up to be a multiple of epflat.gran.
|
||
|
||
|
||
Calls p_leave if there is insufficient memory to reallocate the cell.
|
||
|
||
|
||
& EF_GRANULARITY Set buffer granularity
|
||
|
||
|
||
VOID ef_granularity(UINT gran);
|
||
Set epflat.gran to gran or, if gran 1s zero, set epflat.gran to l.
|
||
|
||
|
||
No attempt is made to alter the current size of the allocated buffer which may, therefore, be incompatible
|
||
with the new granularity.
|
||
|
||
|
||
& EF_SENSE BUF Sense start of data
|
||
|
||
|
||
UINT ef_sense_buf (TEXT **pbuf) ;
|
||
|
||
|
||
Write, to *pbuf, the address of the first byte of the document text, returning the length of the text,
|
||
excluding the terminating zero.
|
||
|
||
|
||
This method, unlike ep_sense_chars, takes advantage of the fact that the whole of the text is stored
|
||
contiguously.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
EPSEG
|
||
|
||
|
||
EPROOT
|
||
Ge
|
||
|
||
|
||
ep_set_text
|
||
ep_scan_word
|
||
ep_word_count
|
||
ep_scan_para
|
||
ep_para_count
|
||
|
||
|
||
ep_scan_block
|
||
|
||
|
||
ep_sense_text
|
||
ep_capacity
|
||
|
||
|
||
ep_init
|
||
ep_sense_len
|
||
ep_sense_chars
|
||
ep_back_chars
|
||
ep_insert
|
||
|
||
|
||
ep_extract
|
||
|
||
|
||
ep_add_para ep_delete
|
||
|
||
|
||
ep_clear
|
||
|
||
|
||
ep_copy_indent
|
||
|
||
|
||
ep_copy_to_front epiinsert
|
||
ep_copy_to_back
|
||
|
||
|
||
ep_compress
|
||
|
||
|
||
ep_paste
|
||
|
||
|
||
ep_mod_chars
|
||
|
||
|
||
EPSEG Stores the document text in a segmented buffer using an instance of scBuF.
|
||
|
||
|
||
This class is intended for use either to store large amounts of text, or where the dynamic range of the
|
||
document size is potentially large.
|
||
|
||
|
||
A typical example is to store the text of a text processor document.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file edit.cl (generated header file edit. g).
|
||
|
||
|
||
CLASS epseg eproot
|
||
Editable paragraphs - segmented storage
|
||
|
||
|
||
REPLACE ep_init
|
||
REPLACE ep_sense_len
|
||
REPLACE ep_sense_chars
|
||
REPLACE ep_back_chars
|
||
REPLACE ep_insert
|
||
REPLACE ep_extract
|
||
REPLACE ep_delete
|
||
REPLACE ep_clear
|
||
REPLACE ep_compress
|
||
PROPERTY 1
|
||
|
||
{
|
||
|
||
PR_SGBUF *b;
|
||
|
||
}
|
||
|
||
|
||
handle of buffers data
|
||
|
||
|
||
}
|
||
Property
|
||
|
||
|
||
the handle of an instance of the scBur segmented buffer class in which the
|
||
text is stored. It should be regarded as read only.
|
||
|
||
|
||
epseg.b
|
||
|
||
|
||
EPSEG methods
|
||
EP_INIT
|
||
|
||
|
||
VOID ep_init (UINT maxlen) ;
|
||
|
||
|
||
Initialise
|
||
|
||
|
||
Initialise, by setting eproot .maxlen tO maxlen, creating an instance of scBur and initialising it with a
|
||
fixed granularity of 64 bytes and then inserting a single nu. character.
|
||
|
||
|
||
Calls p_leave if there is insufficient memory.
|
||
|
||
|
||
6-10
|
||
|
||
|
||
6 EDITABLE DOCUMENTS
|
||
|
||
|
||
& EP_SENSE LEN Sense document length
|
||
|
||
|
||
UINT ep_sense_len (VOID) ;
|
||
|
||
|
||
Returns the number of characters in the document, excluding the terminating zero.
|
||
|
||
|
||
& EP_SENSE CHARS Sense characters forwards
|
||
|
||
|
||
UINT ep_sense_chars (TEXT **pbuf, UINT pos, UINT n);
|
||
Write, to *pbuf, the address of the character at position pos.
|
||
|
||
|
||
Returns the smaller of n and the number of contiguously stored characters at *pbuf, including the zero
|
||
that terminates the document.
|
||
|
||
|
||
& EP_BACK_CHARS Sense characters backwards
|
||
|
||
|
||
UINT ep_back_chars (TEXT **pbuf, UINT pos, UINT n);
|
||
|
||
|
||
Write, to *pbuf, the address of the character whose position is n characters in front of position pos; if n is
|
||
P P
|
||
greater than the number of characters in front of position pos, the address of the first character is taken.
|
||
|
||
|
||
Returns the number of contiguous characters at *pbuf up to, but not including, the character at position
|
||
pos. This value will not exceed n.
|
||
|
||
|
||
EP_INSERT Insert characters
|
||
|
||
|
||
INT ep_insert (UINT pos, TEXT *buf, UINT len);
|
||
Insert 1en characters from *buf, at character position pos.
|
||
|
||
|
||
Inserts nothing and calls p_ieave if there is insufficient memory to perform the insertion (with an
|
||
E_GEN_NOMEMoRY error) or if the resulting document length were to exceed eproot .maxlen (with an
|
||
E_GEN_OVER error).
|
||
|
||
|
||
Returns zero if the insertion is successful. The method is suitable for being called under the protection of
|
||
|
||
|
||
p_enter.
|
||
|
||
|
||
& EP_EXTRACT Copy out characters
|
||
|
||
|
||
VOID ep_extract (UINT pos, TEXT *buf, UINT len);
|
||
|
||
|
||
Copy len characters to *buf, starting with the character at position pos. The position pos must lie within
|
||
the range of the segmented buffer or else p_panic(P_PANIC_sGBUF_1) Will be called.
|
||
|
||
|
||
The user is responsible for supplying a buffer of sufficient length to contain the text.
|
||
|
||
|
||
& EP_DELETE Delete characters
|
||
|
||
|
||
VOID ep_delete(UINT posl1, UINT pos2);
|
||
|
||
|
||
Delete the characters between positions pos1 and pos2, by sending the owned instance of scpur an
|
||
SB_DELETE message.
|
||
|
||
|
||
If the position pos1 lies outside the range of the segmented buffer, p_panic (P_PANIC_SGBUF_1) Will be
|
||
called. Similarly if the position pos2 lies outside the range of the segmented buffer,
|
||
p_panic (P_PANIC_SGBUF_2) will be called.
|
||
|
||
|
||
& EP_CLEAR Clear the document
|
||
|
||
|
||
VOID ep_clear (VOID) ;
|
||
|
||
|
||
Remove any text (by sending the owned instance of scBuF an SB_DELETE message) leaving a document
|
||
containing a single terminating zero.
|
||
|
||
|
||
& EP_COMPRESS Compress allocated storage
|
||
|
||
|
||
VOID ep_compress (VOID) ;
|
||
|
||
|
||
Reduce the size of the owned instance of scpur to the minimum required to contain the document,
|
||
consistent with its granularity of 64 bytes, by sending it an sB_compREss message.
|
||
|
||
|
||
CHAPTER 7
|
||
|
||
|
||
RESOURCE FILES
|
||
|
||
|
||
RSCFILE
|
||
|
||
|
||
pcb
|
||
|
||
ix
|
||
offset
|
||
hftree
|
||
|
||
|
||
destroy
|
||
rs_init
|
||
|
||
|
||
rs_read
|
||
rs_read_buf
|
||
|
||
|
||
The RScFILE class provides a set of services to access the contents of a resource file. Resource files are
|
||
described in the Resource Files chapter of the Additional System Information manual. As mentioned
|
||
there, a resource file may be embedded in an image file and may optionally be Huffman code compressed.
|
||
|
||
|
||
An application that needs a resource file and also uses an application manager (appman) will generally
|
||
pass the FLG_APPMAN_RSCFILE flag to the APPMAN am_init method. This causes an instance of the RSCFILE
|
||
class to be created automatically. The application can then read resources by means of the application
|
||
manager's am_load_resource and am_load_res_buf methods which offer greater functionality than the
|
||
RSCFILE rs_read and rs_read_buf methods. Such users will not require detailed knowledge of the
|
||
RSCFILE Class.
|
||
|
||
|
||
Precursors
|
||
The reader is assumed to understand:
|
||
|
||
e =the p_enter and p_leave error handling services
|
||
Class definition
|
||
|
||
|
||
The RSCFILE class subclasses Root and is defined in the sub-category file appman.cl (with generated
|
||
header file appman.g).
|
||
|
||
|
||
CLASS rscfile root
|
||
Basic access to a resource file which may be embedded in an image file
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE destroy Close channel and destroy
|
||
|
||
ADD rs_init Open a resource file
|
||
|
||
ADD rs_read Read a record into an allocated cell
|
||
ADD rs_read_buf Read a record into a buffer
|
||
|
||
TYPES
|
||
|
||
|
||
{
|
||
typedef struct
|
||
{
|
||
UWORD pos; Index file position
|
||
UWORD len; Index length
|
||
} PR_RSCFILE_HEAD;
|
||
}
|
||
|
||
|
||
PROPERTY
|
||
{
|
||
UBYTE *pcb; resource file channel
|
||
PR_RSCFILE_HEAD ix; header containing index position and length
|
||
UWORD offset; file offset of start of resource data
|
||
ULONG hftree; Huffman tree data
|
||
|
||
|
||
}
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Property
|
||
|
||
rscfile.pcb the currently opened resource file channel handle. It should not be
|
||
accessed by a subclass.
|
||
|
||
rscfile.ix the resource file header, containing the index position and length. It
|
||
should not be accessed by a subclass.
|
||
|
||
rscfile.offset the offset from the start of the file to the start of the resource data (zero
|
||
unless the file is embedded in an image file). It should not be accessed by
|
||
a subclass.
|
||
|
||
rscfile.hftree the Huffman tree data. It should not be accessed by a subclass.
|
||
|
||
|
||
RSCFILE methods
|
||
J DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID) ;
|
||
|
||
|
||
Close the currently opened resource file and supersend the pEstRoy message.
|
||
|
||
|
||
RS_INIT Initialise
|
||
|
||
|
||
INT rs_init (UBYTE *pname) ;
|
||
|
||
|
||
Open a channel to a resource file. The string pointed to by *pname should be the name of either the
|
||
resource file itself, or of an image file containing, in its second add-file slot, an embedded resource file.
|
||
(See the Resource Files chapter of the Additional System Information manual.)
|
||
|
||
|
||
Writes the appropriate values to rscfile.offset, rscfile.ix and, if the resources are Huffman encoded,
|
||
rscfile.hftree.
|
||
|
||
|
||
Calls p_leave on error, otherwise returns zero. The method is suitable for being called under the
|
||
protection of p_enter.
|
||
|
||
|
||
RS READ Allocate buffer and read resource
|
||
INT rs_read(INT rid, UBYTE **ppdata) ;
|
||
Allocate a buffer and read into it the resource with resource id rid.
|
||
|
||
|
||
The length of the resource is read from the file and a buffer of this length is allocated. The resource is
|
||
then read into this buffer and the address of the buffer is written to *ppdata. If the resource file record is
|
||
Huffman encoded then it is decoded before being written to the buffer.
|
||
|
||
|
||
The method calls p_leave on any error (which will be either a memory allocation error or an error while
|
||
attempting to read the file). It is guaranteed that, on error, no memory will have been allocated and
|
||
nothing will have been written to *ppdata.
|
||
|
||
|
||
Returns the length of the resource, including the terminating zero if the resource is a string.
|
||
|
||
|
||
RS READ BUF Read resource
|
||
|
||
|
||
INT rs_read_buf (INT rid, UBYTE *buf);
|
||
|
||
|
||
Read the resource with resource id ria into the buffer pointed to by but. If the resource file record is
|
||
Huffman encoded then it is decoded before being written to the buffer. It is the user's responsibility to
|
||
ensure that the buffer is of sufficient length to contain the resource.
|
||
|
||
|
||
The method calls p_leave on error (which will be an error while attempting to read the file).
|
||
|
||
|
||
Returns the length of the resource, including the terminating zero if the resource is a string.
|
||
|
||
|
||
CHAPTER 8
|
||
|
||
|
||
BINARY FILE MANAGEMENT
|
||
|
||
|
||
The classes described in this chapter provide methods for reading and writing signatured binary files.
|
||
Such files contain a 22 byte standard header consisting of:
|
||
|
||
e a 16 byte file signature (all 16 bytes are significant)
|
||
|
||
e a2 byte file version number
|
||
|
||
|
||
e a2 byte offset from the start of the file to the end of the header (to allow for future expansion of
|
||
the header)
|
||
|
||
|
||
e a2 byte runtime version number
|
||
|
||
|
||
Each version number is a hexadecimal number in the form xyyvr, where:
|
||
|
||
|
||
x is the major version number (4 bits)
|
||
YY is the minor version number (8 bits)
|
||
F is the release type, A (alpha) B (beta) or F (final)
|
||
|
||
|
||
For example, 0x123A is an alpha release of version 1.23.
|
||
|
||
|
||
The runtime version number is intended to specify the minimum version of runtime software (for
|
||
example, OPL) that is required to process the file. If this field is not used it should be set to zero.
|
||
|
||
|
||
Database files are a particular type of signatured binary file. Further information relating to this type of
|
||
file may be found in the Database Files chapter of the PLIB Reference manual and in the ISAM Reference
|
||
manual.
|
||
|
||
Precursors
|
||
|
||
|
||
An understanding of the following topics would prove helpful:
|
||
e the PLIB binary file services, as described in the Files chapter of the PLIB Reference manual.
|
||
|
||
|
||
e =the p_enter and p_leave error handling services
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
om “~~
|
||
— —
|
||
|
||
|
||
bfile : Co iden :
|
||
|
||
|
||
TAN.
|
||
|
||
|
||
{tIvfile ) serfila. /
|
||
~ )
|
||
|
||
|
||
ee ce
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
BFILE
|
||
|
||
|
||
pcb
|
||
rbuf
|
||
rlen
|
||
offset
|
||
|
||
|
||
destroy
|
||
fi_close
|
||
fi_read
|
||
fl_set_buf_len
|
||
fl_sense_data
|
||
|
||
|
||
fi_open
|
||
|
||
|
||
fl_rewind
|
||
|
||
|
||
The methods of the pr1z class provide the basic means of creating, opening, validating and reading
|
||
signatured binary files with arbitrary content.
|
||
|
||
|
||
BFILE must be subclassed to provide additional methods if it is necessary to write to the file.
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file tlvfile.cl (generated header file tlvfile.g).
|
||
|
||
|
||
CLASS bfile root
|
||
{
|
||
REPLACE destroy Close file then destroy
|
||
ADD fi_close Free any buffers
|
||
ADD fi_read Read from file into internal buffer
|
||
ADD fl_set_buf_len Ensure internal buffer is at least len bytes
|
||
ADD fl_sense_data Get length and address of data
|
||
ADD fi_open Open binary file and check signature
|
||
ADD fl_rewind Reposition to first byte after header
|
||
CONSTANTS
|
||
{
|
||
OP_BFILE_ID_SIZE 16 size of text ID
|
||
}
|
||
TYPES
|
||
|
||
|
||
{
|
||
|
||
|
||
typedef struct
|
||
|
||
|
||
{
|
||
|
||
|
||
TEXT fid[OP_BFILE_ID_SIZE]; plain text application ID
|
||
|
||
|
||
UWORD vers; file version number
|
||
UWORD offset; abs. file offset to end of header
|
||
UWORD rtvers; minimum runtime version
|
||
|
||
|
||
}
|
||
|
||
}
|
||
|
||
PROPERTY
|
||
{
|
||
UBYTE
|
||
UBYTE
|
||
UWORD
|
||
UWORD
|
||
}
|
||
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
|
||
bfile.pcb
|
||
|
||
|
||
bfile.rbuf
|
||
bfile.rlen
|
||
|
||
|
||
bfile.offset
|
||
|
||
|
||
OP_BFILE_FSIG;
|
||
|
||
|
||
*pcb; File channel
|
||
|
||
*rbuf; Allocated record buffer
|
||
|
||
rlen; Length of data in read buffer
|
||
offset;
|
||
|
||
|
||
the handle of a currently open file, or nun. It should not be accessed by
|
||
any subclass.
|
||
|
||
|
||
a pointer to an allocated buffer into which file data is read.
|
||
the number of bytes of valid data in the allocated buffer.
|
||
|
||
|
||
the byte offset from the start of the current file to the first byte after the
|
||
file signature.
|
||
|
||
|
||
8 BINARY FILE MANAGEMENT
|
||
|
||
|
||
BFILE methods
|
||
& DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID);
|
||
|
||
|
||
Send an FI_cLosE message and then supersend the DEsTRoy message.
|
||
|
||
|
||
Fl_OPEN Open file
|
||
|
||
|
||
INT fi_open(TEXT *pname, UINT mode, OP_BFILE_SIG *psig) ;
|
||
|
||
|
||
Open the binary file whose full file specification 1s pointed to by pname. The value of mode may be any
|
||
combination of the PLIB file mode flags appropriate for a binary file (it must include p_rsTREAM or, more
|
||
rarely, P_FSTREAM_TEXT).
|
||
|
||
|
||
If a new file is being opened (mode contains either P_FCREATE Or P_FREPLACE) the file signature at «psig is
|
||
written to the newly opened file. Otherwise, the file signature is read from the file and compared with the
|
||
file signature at *psig. If the file signature read from the file is the wrong length, or if the two 16-byte file
|
||
IDs do not match exactly (all sixteen bytes are compared) p_leave (E_FILE_INVALID) is called. The
|
||
validation of the remaining signature fields will vary with the application and is left to the caller. To
|
||
facilitate this validation, the signature read from the file is written to *psig.
|
||
|
||
|
||
Once the file has been successfully opened, the file offset to the first byte following the file header
|
||
(psig->offset) is written to bfile.offset.
|
||
|
||
|
||
Returns zero if successful, or a negative error number for any error other than the E_FILE_INVALID error
|
||
described above.
|
||
|
||
|
||
& FI_CLOSE Close file
|
||
|
||
|
||
VOID fi_close (VOID) ;
|
||
Close any open file, freeing any allocated buffer.
|
||
|
||
|
||
It is safe to send an FI_CLOSE message even if there is no open file.
|
||
|
||
|
||
Fl_READ Read from file
|
||
|
||
|
||
INT fi_read(UINT len);
|
||
Read len bytes from the current position in the currently open file into the allocated buffer.
|
||
|
||
|
||
Sends an FL_SET_BUF_LEN message to ensure that the buffer has room for at least 1en bytes before reading
|
||
the data. If this fails, p_1eave (E_GEN_NOMEMORY) is called.
|
||
|
||
|
||
If the read is successful, sets bfile.rlen to contain the number of bytes read into the buffer.
|
||
|
||
|
||
Returns the number of bytes read, or a negative error.
|
||
|
||
|
||
FL_SET BUF_LEN Set buffer size
|
||
|
||
|
||
VOID fl_set_buf_len(UINT len);
|
||
|
||
|
||
Reallocate, if necessary, the allocated buffer pointed to by bfile.rbuf to ensure that it has room for at
|
||
least 1en bytes. This method will never reduce the size of the buffer.
|
||
|
||
|
||
Calls p_leave if there is insufficient memory to reallocate the buffer.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
& FL_SENSE DATA Sense record data
|
||
|
||
|
||
UINT fl_sense_data(UBYTE **pbuf) ;
|
||
|
||
|
||
Write to *pbuf the address of the allocated buffer and return the length of the data last read into it by the
|
||
fi_read method.
|
||
|
||
|
||
The return value will be zero and the value written to *pbuf will be nut if there is no currently open file,
|
||
or if no FI_READ message has been received.
|
||
|
||
|
||
FL_REWIND Reposition to start
|
||
|
||
|
||
VOID fl_rewind (VOID) ;
|
||
|
||
|
||
Set the current file position to the first byte after the file header.
|
||
|
||
|
||
TLVFILE
|
||
|
||
|
||
TLVFILE
|
||
|
||
|
||
rbuf
|
||
rlen
|
||
offset
|
||
|
||
|
||
destroy fi_open
|
||
fi_close l1_rewind
|
||
fi_read l_write_rec
|
||
fl_set_buf_len
|
||
|
||
|
||
fl_sense_data
|
||
|
||
|
||
_delrec
|
||
_—count
|
||
_read_by_type
|
||
_set_rec
|
||
|
||
|
||
1 sense_rec
|
||
|
||
|
||
FoFH FH FH FH Fh EF SF
|
||
|
||
|
||
l_replace
|
||
|
||
|
||
The TLvr1.e class provides support for signatured binary files that contain type-length-value (TLV)
|
||
records.
|
||
|
||
|
||
Following the standard header, the file is considered to be made up of records, each of which has a 2 byte
|
||
header specifying the record type and length. The most significant nibble of the word contains the record
|
||
type, in the range 0-15. The remaining three nibbles contain the record length and is, therefore, restricted
|
||
to a maximum of 4K bytes.
|
||
|
||
|
||
Records of type 0 are considered to be deleted records. Records of type 15 (OxOf) are reserved to represent
|
||
non-valid records and are treated as though they are deleted records.
|
||
|
||
|
||
For efficient record access, the record number of the next record to be read and the current file position
|
||
are stored in property.
|
||
|
||
|
||
TLV files are designed to be Flash-friendly, i.e. they may be stored and manipulated efficiently in Flash
|
||
SSDs (or any other EPROM medium). A TLV file stored on such a medium may be modified by
|
||
appending, deleting or replacing records without having to make a new copy of the entire file.
|
||
|
||
|
||
Although TLV files may contain in excess of 4,000,000,000 records, TLVF ILE is ideally suited to
|
||
manipulating files which contain a relatively small number of records. If the file contains a large number
|
||
of records, operations which involve non-sequential access may take an extended time to return.
|
||
|
||
|
||
Database files are a form of TLV file with a particular file signature header and specific record content.
|
||
Alternative means of manipulating such files are described in the Database Files chapter of the PLIB
|
||
Reference manual and also in the ISAM Reference manual.
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
8 BINARY FILE MANAGEMENT
|
||
|
||
|
||
Defined in sub-category file tlvfile.cl (generated header file tivfile. g).
|
||
|
||
|
||
CLASS tlvfile bfile
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE fi_open
|
||
REPLACE fl_rewind
|
||
|
||
|
||
ADD
|
||
ADD
|
||
ADD
|
||
ADD
|
||
ADD
|
||
ADD
|
||
ADD
|
||
|
||
|
||
CONS
|
||
|
||
|
||
TYPE
|
||
|
||
|
||
PROP
|
||
|
||
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
|
||
fl_write_rec
|
||
|
||
|
||
Open file
|
||
Reposition to first record, reset property
|
||
Write a TLV record
|
||
|
||
|
||
fl_delrec Delete a record
|
||
f1l_count Get record count
|
||
fl_read_by_type Read record of specified type
|
||
fl_set_rec Set the current record number
|
||
|
||
|
||
fl_sense_rec
|
||
|
||
|
||
fl_replace
|
||
|
||
|
||
Sense the current record number
|
||
Replace a record
|
||
|
||
|
||
TANTS
|
||
|
||
TLV_TYPE_UNKNOWN 0x10
|
||
TLV_TYPE_INVALID Ox0f
|
||
TLV_TYPE_DELETED 0x00
|
||
TLV_TYPE_NORMAL 0x01
|
||
TLV_TYPE_FIELDS 0x02
|
||
TLV_TYPE_SHIFT 12
|
||
TLV_TYPE_MASK Oxf000
|
||
}
|
||
|
||
Ss
|
||
|
||
|
||
typedef struct
|
||
|
||
|
||
{
|
||
|
||
|
||
OP_BFILE_FSIG fsig; Binary file signature
|
||
UWORD types; Valid types
|
||
} OP_TLVFILE;
|
||
|
||
|
||
typedef struct
|
||
|
||
|
||
{
|
||
|
||
|
||
UBYTE
|
||
|
||
|
||
UINT len;
|
||
INT type;
|
||
} OP_TLV_REC;
|
||
|
||
|
||
ERTY
|
||
{
|
||
|
||
UWORD
|
||
UWORD
|
||
UWORD
|
||
ULONG
|
||
ULONG
|
||
}
|
||
|
||
|
||
tlvfile.typmask
|
||
|
||
|
||
tl
|
||
|
||
|
||
ae
|
||
|
||
|
||
tl
|
||
|
||
|
||
ti
|
||
|
||
|
||
lvfil
|
||
|
||
|
||
lvfil
|
||
|
||
|
||
lvfil
|
||
|
||
|
||
le. hdlen
|
||
|
||
|
||
le.hdt
|
||
|
||
|
||
le.pos
|
||
|
||
|
||
lvfil
|
||
|
||
|
||
ype
|
||
|
||
|
||
le.fpos
|
||
|
||
|
||
typmask;
|
||
hdlen;
|
||
hdtype;
|
||
Pos;
|
||
fpos;
|
||
|
||
|
||
*Du Es.
|
||
|
||
|
||
valid record type mask
|
||
|
||
length of header
|
||
|
||
type from header
|
||
|
||
Next record to be read
|
||
|
||
Current file position, for validation
|
||
|
||
|
||
which record types are considered valid. For example, the value 0x32 (bits
|
||
1, 4 and 5 set) indicates that records of type 1, 4 and 5 are valid. Records
|
||
of other types are treated as if they do not exist.
|
||
|
||
|
||
the current record length as decoded from the first word of the record. It
|
||
should not be accessed by a subclass.
|
||
|
||
|
||
the current record type as decoded from the first word of the record. It
|
||
should not be accessed by a subclass.
|
||
|
||
|
||
the current record number that corresponds to the file position,
|
||
tlvfile.fpos. It should not be accessed by a subclass.
|
||
|
||
|
||
the current file position. It should not be accessed by a subclass.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TLVFILE methods
|
||
|
||
|
||
All methods which read a record assume that the current file position is at the start of a record.
|
||
|
||
|
||
Fl_OPEN Open TLV file
|
||
|
||
|
||
INT fi_open(TEXT *fspec, UINT mode, OP_TLVFILE *psig):
|
||
|
||
|
||
Open the TLV file whose full file specification is pointed to by fspec. The value of mode may be any
|
||
combination of the PLIB file mode flags appropriate for a binary file (it must include p_rsTREaAM).
|
||
|
||
|
||
Opens the file by supersending the r1_oPzn message which, if opening an existing file, validates the 16-
|
||
byte file signature ID and overwrites psig->fsig (but not psig—>types) with the signature read from the
|
||
file.
|
||
|
||
|
||
Calls p_ieave if the file signature validation fails.
|
||
|
||
|
||
Sets tlvfile.typmask to the value of psig->types and sends itself an rL_REWIND message to position to
|
||
the start of the first record.
|
||
|
||
|
||
Returns zero if successful or error values as returned by the Br1Lz superclass.
|
||
|
||
|
||
FL_REWIND Reposition to start
|
||
VOID fl_rewind (VOID) ;
|
||
Position to the first byte following the file signature.
|
||
|
||
|
||
Supersends the rL_REwIND message and then sets tivfile.fpos tO bfile.offset, and tlvfile.pos to
|
||
zero.
|
||
|
||
|
||
Calls p_1eave on error.
|
||
|
||
|
||
FL_COUNT Count records
|
||
|
||
|
||
VOID fl_count (ULONG *pcount) ;
|
||
|
||
|
||
Write to *pcount the number of valid records (those whose types are specified by tivfile.typmask) in the
|
||
file.
|
||
|
||
|
||
Counts the records by scanning the entire file and then sends an rL_REWIND message to reposition to the
|
||
first record.
|
||
|
||
|
||
Calls p_leave on error.
|
||
|
||
|
||
FL_WRITE_REC Write a record
|
||
|
||
|
||
VOID fl_write_rec(UBYTE *buf, UINT len, UINT type);
|
||
Append a new record of type type, containing the first 1en bytes of the data pointed to by bue.
|
||
If any error occurs, the record is either not written or is marked as not being a valid record.
|
||
|
||
|
||
All errors result in p_leave being called.
|
||
|
||
|
||
FL_SET REC Set current record
|
||
|
||
|
||
INT fl_set_rec(UINT lsw, UINT msw);
|
||
INT fl_set_rec(ULONG recnum) ; (conceptual)
|
||
|
||
|
||
Position to, and read into the internal buffer, record number recnum (counting only records of types
|
||
specified by t1vfile.typmask). The uLONG recnum is actually passed in the message as two UINT
|
||
parameters, 1sw (least significant word) and msw (most significant word).
|
||
|
||
|
||
Returns the positive record type if successful, or =_F1LE_koF if reading past the end of the file. Other file
|
||
errors result in a call to p_leave. The content of the internal buffer is unpredictable in the event of an
|
||
error.
|
||
|
||
|
||
8-6
|
||
|
||
|
||
8 BINARY FILE MANAGEMENT
|
||
|
||
|
||
& FL_SENSE REC Sense current record number
|
||
|
||
|
||
VOID fl_sense_rec(ULONG *prec);
|
||
Write, to *prec, the record number of the record following the one which has last been read.
|
||
|
||
|
||
Writes zero if no records have been read since the receipt of an FL_REWIND message.
|
||
|
||
|
||
FL_DELREC Delete a record
|
||
|
||
|
||
VOID fl_delrec(UINT lsw, UINT msw);
|
||
VOID fl_delrec(ULONG recnum) ; (conceptual)
|
||
|
||
|
||
Delete record recnum (counting only records of types specified by t1vfile.typmask) by overwriting its
|
||
record type with type 0. The uLonc recnum is actually passed in the message as two uINT parameters, 1sw
|
||
(least significant word) and msw (most significant word).
|
||
|
||
|
||
Calls p_1eave on error, in which case the record may not have been deleted. It is the user's responsibility
|
||
to determine whether the record has been deleted (for example, by testing the number of records).
|
||
|
||
|
||
FL_REPLACE Replace a record
|
||
|
||
|
||
VOID fl_replace(UINT lsw, UINT msw, OP_TLV_REC *prec);
|
||
VOID fl_replace(ULONG recnum, OP_TLV_REC *prec); (conceptual)
|
||
|
||
|
||
Replace a record by deleting record recnum (counting only records of types specified by tivfile.typmask)
|
||
and then appending the record specified by prec. The uLoNG recnum is actually passed in the message as
|
||
two UINT parameters, 1sw (least significant word) and msw (most significant word).
|
||
|
||
|
||
Deletes the record by sending itself an rL_pELETE message and, if this is successful, appends the new
|
||
record by sending itself an FL_wRITE_REC message.
|
||
|
||
|
||
Calls p_leave on error, in which case the original record may not have been deleted. If it has been
|
||
deleted, the new record will either not have been appended or will have been marked as not being a valid
|
||
record.
|
||
|
||
|
||
FL_READ BY_TYPE Read record of specific type(s)
|
||
|
||
|
||
INT fl_read_by_type(UINT type);
|
||
|
||
|
||
Search forwards from the current file position and read into the internal buffer the first record whose type
|
||
is one of those specified by the bitmask in type irrespective of the types specified by tivfile.typmask.
|
||
|
||
|
||
Returns the record type of the record or, if the end of the file is reached before finding a record of a
|
||
matching type, it returns E_FILE_EOF.
|
||
|
||
|
||
Calls p_1eave for all other errors.
|
||
|
||
|
||
This method should be used with caution. If it skips records that would normally be read (because they are
|
||
included in t1ivfile.typmask) it may result in tivfile.pos containing an incorrect value. If there is any
|
||
doubt, this method should always be followed by the sending of an rL_REWIND message.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TLVDATA
|
||
|
||
|
||
TLVDATA
|
||
|
||
|
||
td_open
|
||
td_save
|
||
td_changed
|
||
td_load_item
|
||
td_save_item
|
||
td_reset
|
||
|
||
|
||
td_set_file
|
||
td_set_item
|
||
td_sense_item
|
||
|
||
|
||
The tivpata abstract class provides the basic mechanisms for manipulating data that is stored in a series
|
||
of records (each with a different record type) in a TLV file.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file tlvfile.cl (generated header file tlvfile.g).
|
||
|
||
|
||
CLASS tlvdata root
|
||
|
||
|
||
Data which is loaded and saved to a tlvfile
|
||
{
|
||
ADD td_open Open file or revert to file
|
||
ADD td_save Save modifications to file
|
||
ADD td_changed Return TRUE if data changed since load
|
||
ADD td_load_item Load an item
|
||
ADD td_save_item Save an item
|
||
ADD td_reset=p_dummy Clear data structures
|
||
DEFER td_set_file Set the file characteristics
|
||
DEFER td_set_item Set an item
|
||
DEFER td_sense_item Sense an item
|
||
TYPES
|
||
{
|
||
typedef struct
|
||
{
|
||
OP_TLVFILE tlvfile; File signature and mask
|
||
TEXT ext[6]; Default extension
|
||
} PR_TLVDATA_CHARS;
|
||
}
|
||
PROPERTY 1
|
||
{
|
||
PR_TLVFILE *tlv; Handle to tlvfile
|
||
UWORD cl_tlv; Clean id for tlv file
|
||
UWORD changed; TRUE if data changed since load
|
||
WORD index; Index for load and save
|
||
WORD tmask; Valid record mask
|
||
TEXT name [P_FNAMESIZE]; Parameter file name
|
||
}
|
||
}
|
||
Property
|
||
tlv the handle of a temporary instance of the TLvr1ue class. It should not be
|
||
accessed by a subclass.
|
||
cl_tlv the cleanup id for the TLvF1Lz instance, used for roll-back on error. It
|
||
|
||
|
||
should not be accessed by a subclass.
|
||
|
||
|
||
8 BINARY FILE MANAGEMENT
|
||
|
||
|
||
changed a flag indicating that the data has changed since a previous load or save.
|
||
A subclass must set this to TRUE to signal that changed data requires
|
||
saving. A subclass is not expected to set a FALSE value.
|
||
|
||
|
||
index the type of the last record for which data has been sensed by the
|
||
td_save_item method. It should not be accessed by a subclass.
|
||
|
||
tmask the mask of valid record types. It should not be accessed by a subclass.
|
||
|
||
name the full file specification of the file last used in the tad_open method. It
|
||
|
||
|
||
should not be accessed by a subclass.
|
||
|
||
|
||
TLVDATA methods
|
||
TD_OPEN Open and read file
|
||
|
||
|
||
INT td_open(TEXT *name) ;
|
||
Open a TLV file, read all its records into memory, overwriting any existing data, and close it again.
|
||
|
||
|
||
Sends itself a r>D_RESET message and then opens, reads and closes the file specified by name. If name is
|
||
NULL, the file opened by a previous td_open Or td_save is reopened, otherwise name should point to a
|
||
string containing the name of the file to open.
|
||
|
||
|
||
Before opening the file, a T>_sET_FILE message is sent to determine the appropriate file characteristics
|
||
and extension. If not nut, the passed name is parsed (the related name being the file extension resulting
|
||
from the Tp_sET_FILE message) into the t1vdata.name buffer.
|
||
|
||
|
||
An instance of TLVFILE 1s created and used to open the file and read each record in turn. As each record is
|
||
read, a TD_LOAD_ITEM message is sent, to store the record's content. When all the records have been read
|
||
the TLVFILE instance is destroyed (which automatically closes the file). On successful conclusion the value
|
||
of tlvdata.changed iS Set tO FALSE.
|
||
|
||
|
||
Returns zero if successful, or E_r1LE_nx1st if the specified file does not exist.
|
||
|
||
|
||
All other errors result in p_leave being called.
|
||
|
||
|
||
TD_SAVE Save data to file
|
||
|
||
|
||
VOID td_save (TEXT *name) ;
|
||
|
||
|
||
Write the current data to the TLV file specified by name, replacing any existing file. If name is nuLL, the
|
||
file opened by a previous td_open or td_save is reopened, otherwise name should point to a string
|
||
containing the name of the file to open.
|
||
|
||
|
||
Before opening the file, a Tt>_sET_FILE message is sent to determine the appropriate file characteristics
|
||
and extension. If not nut, the passed name is parsed (the related name being the file extension resulting
|
||
from the TD_SET_FILE message) into the t1vdata.name buffer.
|
||
|
||
|
||
An instance of TLVFILE 1s created and used to open the file (to replace any existing file) and write the
|
||
records. The data, length and type of each record is determined by sending a Tp_savE_ITEM message.
|
||
When this message returns zero, indicating that there are no further records, the TLvFILE instance is
|
||
destroyed (which automatically closes the file). On successful conclusion the value of t1vdata.changed 1S
|
||
set tO FALSE.
|
||
|
||
|
||
Any error results in p_leave being called.
|
||
|
||
|
||
& TD_CHANGED Check if changed
|
||
|
||
|
||
INT td_changed (VOID);
|
||
|
||
|
||
Return TRuzE if the data has been changed since a load or a save.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TD_LOAD ITEM Process a record read from a file
|
||
|
||
|
||
VOID td_load_item(INT type, UBYTE *buf, UINT len);
|
||
|
||
|
||
Process the record by sending a TD_SET_ITEM message.
|
||
|
||
|
||
TD_SAVE_ITEM Get a record to be saved
|
||
|
||
|
||
INT td_save_item(UBYTE **pbuf, UWORD *plen);
|
||
Determine the type of the next record to be saved and send a Tp_sENSE_ITEM message to sense its data.
|
||
The method uses tivdata.index and tlvdata.tmask to identify the record type.
|
||
|
||
|
||
Returns the record type, or zero if there are no further records to be saved.
|
||
|
||
|
||
& TD_RESET Reset all data
|
||
|
||
|
||
VOID td_reset (VOID) ;
|
||
|
||
|
||
The supplied method does nothing. It is expected to be subclassed to perform any appropriate reset action.
|
||
|
||
|
||
Deferred TLVDATA methods
|
||
|
||
|
||
TD_SET FILE Set the TLV file characteristics
|
||
|
||
|
||
VOID td_set_file(PR_TLVDATA_CHARS *pfc)j;
|
||
|
||
|
||
Write the appropriate TLV file signature header (including the mask of valid record types) and file
|
||
extension to the PR_TLVDATA_CHARs Struct pointed to by pfc.
|
||
|
||
|
||
On entry, pfc->ext [0] contains the character '.' and pfc->tlvfile.fsig.offset is already set to
|
||
sizeof (OP_BFILE_FSIG). All other bytes are set to zero.
|
||
|
||
|
||
TD_SET_ITEM Set in-memory data for a record
|
||
|
||
|
||
VOID td_set_item(INT type, VOID *buf, UINT len);
|
||
|
||
|
||
Store, in memory, the data for a record of type type and of length 1en, pointed to by buf.
|
||
|
||
|
||
TD_SENSE_ITEM Sense in-memory data for a record
|
||
INT td_sense_item(INT type, VOID **pbuf) ;
|
||
Write to *pbuf a pointer to the data for a record of type type.
|
||
|
||
|
||
Returns the length of the data.
|
||
|
||
|
||
SERFILE
|
||
|
||
|
||
TLVDATA
|
||
|
||
|
||
td_open
|
||
td_save
|
||
td_changed
|
||
td_load_item
|
||
|
||
|
||
SERFILE
|
||
|
||
|
||
serial
|
||
modem
|
||
inkdvr
|
||
serdvr
|
||
file
|
||
|
||
|
||
td_reset
|
||
td_set_file
|
||
td_set_item
|
||
td_sense_item
|
||
|
||
|
||
8 BINARY FILE MANAGEMENT
|
||
|
||
|
||
td_save_item
|
||
|
||
|
||
The serFr1.e class provides the methods for manipulating serial port parameter data saved in a .trm TLV
|
||
file.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file tlvfile.cl (generated header file tivfile. g).
|
||
|
||
|
||
CLASS serfile tlvdata
|
||
{
|
||
REPLACE td_reset Set defaults
|
||
REPLACE td_set_file Set the file characteristics
|
||
REPLACE td_set_item
|
||
REPLACE td_sense_item
|
||
|
||
|
||
Set an item
|
||
Sense an item
|
||
|
||
|
||
CONSTANTS
|
||
TE_MASK_SERIAL 0x0001
|
||
TE_MASK_MODEM 0x0002
|
||
TE_MASK_FILE 0x0004
|
||
TY_SERFILE_SERIAL 1
|
||
OBSOLETE_SERFILE_MODEM Z
|
||
TY_SERFILE_FILE 3
|
||
TY_SERFILE_NEW_MODEM 4
|
||
TY_SERFILE_SERDVR 5
|
||
TY_SERFILE_LNKDVR 6
|
||
TE_XMDM_NONE 3
|
||
TE_DIAL_PULSE 1
|
||
TE_DIAL_TONE 2
|
||
TE_MODEM_300 0x01
|
||
TE_MODEM_1200 0x02
|
||
TE_MODEM_2400 0x03
|
||
TE_MODEM_4800 0x04
|
||
TE_MODEM_9600 0x05
|
||
TE_MODEM_19200 0x06
|
||
MAX_DEVICE_NAME 10 ! TTY.AS5:A plus zero terminator
|
||
MAX_MODEM_CMD 40
|
||
|
||
|
||
}
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TYPES
|
||
|
||
{
|
||
|
||
typedef struct
|
||
{
|
||
! Serial port
|
||
P_SRCHAR ch; Serial port characteristics
|
||
TEXT port [P_MAXDEVNAME+2]; Serial port to use
|
||
} PF_SERIAL;
|
||
|
||
typedef struct
|
||
{
|
||
! New Modem driver
|
||
P_MDMCHR mch;
|
||
|
||
|
||
UBYTE phone[25]; Phone number
|
||
|
||
UBYTE auto_dial; TRUE if modem to auto dial on connection
|
||
UBYTE mdmdvr [MAX_DEVICE_NAME]; Modem driver to use (if any)
|
||
|
||
UBYTE mdmcmd [MAX_MODEM_CMD]; Max extra configuration for modem
|
||
|
||
|
||
UBYTE spare[16];
|
||
} PF_MODEM;
|
||
typedef struct
|
||
{
|
||
! File transfer
|
||
UWORD protocol; File transfer protocol
|
||
} PF_FILE;
|
||
|
||
|
||
typedef struct
|
||
{
|
||
! New Serial port
|
||
P_SRCHAR ch; Serial port characteristics
|
||
UBYTE serdvr[MAX_DEVICE_NAME]; Serial driver to use
|
||
UBYTE spare[16];
|
||
} PF_SERDVR;
|
||
|
||
typedef struct
|
||
{
|
||
! Link drivers
|
||
UBYTE masdvr [MAX_DEVICE_NAME]; Media access driver to use
|
||
UBYTE lnkdvr[MAX_DEVICE_NAME]; Link driver to use
|
||
UBYTE spare[16];
|
||
} PF_LNKDVR;
|
||
|
||
}
|
||
|
||
PROPERTY
|
||
|
||
{
|
||
|
||
PF_SERIAL serial;
|
||
|
||
PF_MODEM modem;
|
||
|
||
PF_FILE file;
|
||
|
||
PF_LNKDVR Inkdvr;
|
||
|
||
PF_SERDVR serdvr;
|
||
|
||
}
|
||
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
Each item of property represents the data that may be stored in a record of a serial parameter .trm file.
|
||
serfile.serial the data for a serial port record, of record type Ty_SERFILE_SERIAL.
|
||
serfile.modem the data for a modem driver record, of record type
|
||
|
||
|
||
TY_SERFILE_NEW_MODEM.
|
||
serfile.file the data for a file transfer record, of record type Ty_SERFILE_FILE.
|
||
|
||
|
||
serfile.inkdvr the data for a link and media access driver record, of record type
|
||
TY_SERFILE_LNKDVR.
|
||
|
||
|
||
serfile.serdvr the data for an extended format serial driver record, of record type
|
||
TY_SERFILE_SERDVR.
|
||
|
||
|
||
8 BINARY FILE MANAGEMENT
|
||
|
||
|
||
SERFILE methods
|
||
|
||
|
||
& TD_RESET Reset all data
|
||
VOID td_reset (VOID);
|
||
|
||
Set the serial data to its default values and then set tivdata.changed tO TRUE.
|
||
|
||
Sets the property data as follows:
|
||
|
||
|
||
serfile.serial
|
||
|
||
|
||
ch. hand P_OBEY_XOFF | P_SEND_XOFF|P_IGN_CTS
|
||
ch.frame P_DATA_8
|
||
|
||
ch.tbaud P_BAUD_9600
|
||
|
||
ch.rbaud P_BAUD_9600
|
||
|
||
ch.xon 0x11 (DC1)
|
||
|
||
ch. xoff 0x13 (DC3)
|
||
|
||
ch. flags P_IGNORE_PARITY
|
||
|
||
port WTTY SA".
|
||
|
||
|
||
serfile.modem
|
||
mch. supported P_SRINQ_300|P_SRINQ_1200|P_SRINQ_2400|P_SRINQ_4800|P_SRINQ_9600|P_SR
|
||
mch.baudrate INQ_19200
|
||
mch.chand P_BAUD_2400
|
||
mch.options P_OBEY_DSR|P_FAIL_DSR|P_OBEY_DCD|P_FAIL_DCD|P_OBEY_XOFF |P_SEND_XOFF
|
||
P_MDM_NO_MODULATION
|
||
|
||
|
||
serfile.file
|
||
protocol TE_XMDM_NONE
|
||
|
||
|
||
serfile.serdvr
|
||
|
||
|
||
ch.hand P_IGN_CTS
|
||
ch.frame P_DATA_8
|
||
ch.tbaud P_BAUD_19200
|
||
ch.rbaud P_BAUD_19200
|
||
serdvr WT AP
|
||
|
||
|
||
serfile.lnkdvr
|
||
masdvr "MAS:"
|
||
inkdvr ®LECE*
|
||
|
||
|
||
All fields not explicitly mentioned above are zero-filled.
|
||
|
||
|
||
& TD_SET FILE Set the serial file characteristics
|
||
|
||
|
||
VOID td_set_file(PR_TLVDATA_CHARS *pfc);
|
||
|
||
|
||
Set the serial file signature, extension and record type mask in the pR_TLVDATA_cHARS Struct pointed to by
|
||
pfc.
|
||
|
||
|
||
The file signature is set to "TRM FILE" (with the remainder of the 16 bytes zero-filled) and the file name
|
||
extension to ". TRM". The type mask is set for record types Ty_SERFILE_SERIAL, TY_SERFILE_NEW_MODEM,
|
||
TY_SERFILE_FILE, TY_SERFILE_SERDVR and Ty_SERFILE_LNKDVR.
|
||
|
||
|
||
& TD SET ITEM Set in-memory data for a record
|
||
|
||
|
||
VOID td_set_item(INT type, VOID *buf);
|
||
|
||
|
||
Set the contents one of the five items of property corresponding to the record of type type, from the
|
||
contents of *buf, where type is one of Ty_SERFILE_SERIAL, TY_SERFILE_NEW_MODEM, TY_SERFILE_FILE,
|
||
TY_SERFILE_SERDVR OF TY_SERFILE_LNKDVvR and buf correspondingly points to a pF_SERIAL, PF_MODEM,
|
||
PF_FILE, PF_SERDVR OF PF_LNKDVR Struct.
|
||
|
||
|
||
Sets tivdata.changed tO TRUE.
|
||
|
||
|
||
8 - 13
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
& TD SENSE ITEM Sense in-memory data for a record
|
||
|
||
|
||
INT td_sense_item(INT type, VOID **pbuf) ;
|
||
|
||
|
||
Write to *pbur the address of one of the five items of property corresponding to the record of type type,
|
||
where type is one of Ty_SERFILE_SERIAL, TY_SERFILE_NEW_MODEM, TY_SERFILE_FILE,
|
||
TY_SERFILE_SERDVR OF TY_SERFILE_LNKDvr. The address written to *pbuf is a corresponding pointer to a
|
||
PF_SERIAL, PF_MODEM, PF_FILE, PF_SERDVR Of PF_LNKDvR Struct.
|
||
|
||
|
||
Returns the length of the record data.
|
||
|
||
|
||
CHAPTER 9
|
||
|
||
|
||
THE CLEANUP CLass
|
||
|
||
|
||
VAROOT VAFIX VAFLAT CLEANUP
|
||
|
||
|
||
nrec key rlen gran level
|
||
nspc
|
||
base
|
||
|
||
destroy vwarrepiace
|
||
|
||
|
||
va_replace | va_init destroy
|
||
|
||
|
||
va_count va_copy va_compress cl_init
|
||
|
||
|
||
va_delete va_reclen va_deletem cl_add
|
||
|
||
|
||
va_sort va_swap va_insertm cl_remove
|
||
|
||
|
||
va_key
|
||
|
||
|
||
va_findisgq
|
||
|
||
|
||
va_insertisq
|
||
|
||
|
||
va_capacity
|
||
va_prec
|
||
|
||
|
||
va_pbuf
|
||
|
||
|
||
cl_clean_item
|
||
cl_clean_level
|
||
cl_set_level
|
||
|
||
|
||
va_append
|
||
va_insert
|
||
va_search
|
||
va_compare
|
||
va_reset
|
||
|
||
|
||
va_test
|
||
|
||
|
||
The cLeanup class supplies one of the main mechanisms by which resources may be released following an
|
||
error condition.
|
||
|
||
|
||
A typical use is in a case where a program allocates, say, a sequence of cells which must either exist as a
|
||
whole or not at all. If, during the allocate sequence, one of the later allocations fails, the previously
|
||
allocated cells must be freed.
|
||
|
||
|
||
The recovery process can be simplified if each cell is placed in a cleanup list as it is allocated. Once the
|
||
whole sequence of allocations is complete the items may be removed from the list. If, however, there is a
|
||
failure in one of the later stages, the previously allocated cells can be freed by the sending of, for example,
|
||
a single CL_CLEAN_LEVEL message. Note that the process of adding an item to the cleanup list is so
|
||
arranged that the addition itself can never fail due to shortage of memory.
|
||
|
||
|
||
Normally, an instance of the cLEanup class is created as a component of the application manager (see the
|
||
Application Manager chapter of this manual). In this case the cleaning up of partially complete
|
||
allocations is generally handled automatically whenever an error occurs and the programmer's
|
||
responsibility is reduced to adding items to, and removing items from, the cleanup list at the appropriate
|
||
times.
|
||
|
||
|
||
Because the addition and removal of items from a cleanup list that is a component of the application
|
||
manager is so common, a set of convenience functions are provided. These are described in a separate
|
||
section at the end of this chapter.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e variable arrays of fixed length records
|
||
|
||
|
||
e =the p_enter and p_leave error handling services
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
ae ae
|
||
¢ Varoot /
|
||
as )
|
||
bee
|
||
aon ae
|
||
( Vafix /
|
||
~ Sash
|
||
Me
|
||
A ee
|
||
( Vaflat /
|
||
)
|
||
eee
|
||
(cleanup /
|
||
= )
|
||
eee
|
||
|
||
|
||
Defined in sub-category file appman.cl (generated header file appman.g).
|
||
|
||
|
||
CLASS cleanup vaflat
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE destroy
|
||
|
||
|
||
ADD
|
||
ADD
|
||
ADD
|
||
ADD
|
||
ADD
|
||
ADD
|
||
|
||
|
||
cl_init
|
||
|
||
cl_add
|
||
cl_remove
|
||
cl_clean_item
|
||
cl_clean_level
|
||
cl_set_level
|
||
|
||
|
||
CONSTANTS
|
||
|
||
|
||
TYPES
|
||
|
||
|
||
}
|
||
|
||
|
||
typedef struct
|
||
|
||
|
||
typedef struct
|
||
|
||
|
||
}
|
||
|
||
|
||
PROPERTY
|
||
|
||
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
|
||
{
|
||
UWORD level;
|
||
}
|
||
|
||
|
||
cleanup.level
|
||
|
||
|
||
Destroy all items in cleanup list
|
||
Initialise cleanup table
|
||
|
||
Add an item for cleanup
|
||
|
||
Remove an item (without cleanup)
|
||
Clean up an item
|
||
|
||
Clean up all items at current level
|
||
Set the cleanup level
|
||
|
||
|
||
TY_CLEANUP_DYL -5 A dyl handle
|
||
|
||
TY_CLEANUP_SHARED -4 A shared allocated cell
|
||
TY_CLEANUP_VOID -3 Already cleaned up
|
||
|
||
TY_CLEANUP_ALLOC -2 An allocated cell
|
||
|
||
TY_CLEANUP_IOCHAN -1 An IO channel
|
||
|
||
TY_CLEANUP_OBJECT 0 An object (O_DESTROY method number !!)
|
||
|
||
|
||
BYTE type; Type of resource
|
||
UBYTE level; Cleanup level
|
||
HANDLE h; Handle of resource
|
||
|
||
|
||
RC_CLEANUP;
|
||
|
||
|
||
UWORD nref;
|
||
SHARED_ALLOC;
|
||
|
||
|
||
current cleanup level
|
||
|
||
|
||
the current cleanup level; set by c1_set_1leve1 and used by
|
||
elclean_level
|
||
|
||
|
||
9 THE CLEANUP CLASS
|
||
|
||
|
||
CLEANUP Methods
|
||
J DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID) ;
|
||
|
||
|
||
Clean up all items in the cleanup list and supersend a pEsTRoy message.
|
||
|
||
|
||
CL_INIT Initialise list
|
||
|
||
|
||
VOID cl_init (UINT num);
|
||
Initialise the cleanup list.
|
||
|
||
|
||
Sends itself a va_inrT message to initialise the array for records of length sizeof (RC_CLEANUP), With a
|
||
granularity of num. Then sends itself a va_capacitTy message to set the capacity to num records and ensures
|
||
that the array contains at least one empty cleanup slot (of type Ty_cLEANUP_VvoID).
|
||
|
||
|
||
CL_ADD Add item
|
||
|
||
|
||
UINT cl_add(UINT type, HANDLE h);
|
||
Add an item to the cleanup list of type type and handle h to the cleanup list at the current cleanup level.
|
||
|
||
|
||
The possible values of type are:
|
||
|
||
|
||
TY_CLEANUP_OBJECT h is the handle of an object, as returned by p_new
|
||
|
||
TY_CLEANUP_IOCHAN h is the pointer to the channel control block, as set by p_open
|
||
|
||
TY_CLEANUP_ALLOC h is the pointer to the allocated cell, as returned by p_alloc
|
||
|
||
TY_CLEANUP_SHARED h is the pointer to a shared allocated cell, as returned by p_alloc (the first
|
||
word of a shared allocated cell is assumed to contain a usage count)
|
||
|
||
TY_CLEANUP_DYL h is the category handle of a loaded dynamic library, as set by p_loadlib
|
||
|
||
|
||
All other values of type, except for Ty_cLEANUP_VvOID, are assumed to relate to objects and behave in a
|
||
way similar to Ty_cLEANUP_oBJECT. In all such cases h is assumed to be the handle of the object as
|
||
returned by p_new. When such an item is cleaned up, it is sent a message with message number equal to
|
||
the value of type. The value ry_cLEanup_oBuectT (0) is chosen specifically to correspond to a DESTROY
|
||
message.
|
||
|
||
|
||
A subclasser who adds further types should respect the current scheme by using a negative number for
|
||
each new type leaving positive numbers to represent object message numbers.
|
||
|
||
|
||
Returns an index number which identifies the newly added item in the cleanup list.
|
||
|
||
|
||
The cl_add method may call p_leave (f_GEN_NOMEMoRY), but not until after the current item has been
|
||
added to the cleanup list. Thus an item cannot be 'lost' by a failure when adding it to the cleanup list.
|
||
|
||
|
||
J CL_ REMOVE Remove item
|
||
|
||
|
||
VOID cl_remove (UINT num);
|
||
|
||
|
||
Remove the item specified by num (as returned by an earlier cL_app message) from the cleanup list without
|
||
cleaning up its associated resource(s).
|
||
|
||
|
||
The item is removed by setting its type to Ty_cLEANUP_vorp. No memory is freed.
|
||
|
||
|
||
JCL_CLEAN ITEM Delete item
|
||
|
||
|
||
VOID cl_clean_item(UINT num);
|
||
|
||
|
||
Clean up the resource(s) associated with item num (as returned by an earlier cL_app message) and remove
|
||
the item from the cleanup list.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
The cleanup action depends on the type of the item as follows:
|
||
|
||
|
||
TY_CLEANUP_IOCHAN close the channel, using p_close
|
||
|
||
TY_CLEANUP_ALLOC free the allocated cell, using p_free
|
||
|
||
TY_CLEANUP_SHARED decrement the usage count of the shared allocated cell and, if decremented to
|
||
zero, free the cell
|
||
|
||
TY_CLEANUP_DYL unload the dynamic library, using p_unloadlib
|
||
|
||
|
||
All other values are assumed to relate to an object and the object is sent a message with message number
|
||
equal to the type. The special case of type Ty_cLEANUP_oBJEcT (0) corresponds to the sending of a DEsTRoY
|
||
message.
|
||
|
||
|
||
No allocated memory associated with the cleanup list's array is freed, but the item's type is set to
|
||
TY_CLEANUP_vorn So that it is available for re-use.
|
||
|
||
|
||
J CL_CLEAN LEVEL Delete all items at current level
|
||
|
||
|
||
VOID cl_clean_level (VOID);
|
||
|
||
|
||
Clean up all items that have been added at the current cleanup level (by sending a series of
|
||
CL_CLEAN_ITEM messages).
|
||
|
||
|
||
JCL_SET LEVEL Set cleanup level
|
||
|
||
|
||
VOID cl_set_level(UINT level);
|
||
|
||
|
||
Set the current cleanup level, stored in cleanup. level, tO level.
|
||
|
||
|
||
CLEANUP convenience functions
|
||
|
||
|
||
These convenience functions assume that an instance of the cLEanup class has been created during the
|
||
initialisation of an instance of the application manager, and that its handle is stored in the application
|
||
manager's property appman.clean. An application should ensure that the application manager's property
|
||
is accessible via the 'magic static’ w_am.
|
||
|
||
|
||
cl_add Add an item
|
||
|
||
|
||
INT cl_add(INT type, VOID *p);
|
||
Add an item, with handle p and of the specified type, to the cleanup list. The value of type may be one of:
|
||
|
||
|
||
TY_CLEANUP_OBJECT
|
||
TY_CLEANUP_IOCHAN
|
||
TY_CLEANUP_ALLOC
|
||
TY_CLEANUP_SHARED
|
||
TY_CLEANUP_DYL
|
||
|
||
|
||
Calling this function is equivalent to:
|
||
p_send4 (w_am—->appman.clean,O_CL_ADD,type,p) ;
|
||
Returns an index number which identifies the newly added item in the cleanup list.
|
||
|
||
|
||
The function may call p_leave (E_GEN_NOMEMOoRY) , but not until after the item has been added to the
|
||
cleanup list.
|
||
|
||
|
||
cl_add_ object Add an object
|
||
|
||
|
||
INT cl_add_object (VOID *p);
|
||
Add an object, with handle p, to the cleanup list.
|
||
Calling this function is equivalent to calling:
|
||
|
||
|
||
cl_add(TY_CLEANUP_OBJECT,p) ;
|
||
|
||
|
||
9 THE CLEANUP CLASS
|
||
|
||
|
||
Returns an index number which identifies the newly added item in the cleanup list.
|
||
|
||
|
||
The function may call p_leave (E_GEN_NOMEMOoRY) , but not until after the item has been added to the
|
||
cleanup list.
|
||
|
||
cl_add_iochan Add an I/O channel
|
||
INT cl_add_iochan (VOID *p);
|
||
|
||
Add an I/O channel, with handle p, to the cleanup list.
|
||
|
||
Calling this function is equivalent to calling:
|
||
|
||
|
||
cl_add(TY_CLEANUP_IOCHAN, p) ;
|
||
|
||
|
||
Returns an index number which identifies the newly added item in the cleanup list.
|
||
|
||
|
||
The function may call p_leave (E_GEN_NOMEMOoRY) , but not until after the item has been added to the
|
||
cleanup list.
|
||
|
||
|
||
cl_add_alloc Add an allocated cell
|
||
INT cl_add_alloc(VOID *p);
|
||
Add an allocated heap cell, with handle p, to the cleanup list.
|
||
|
||
|
||
Calling this function is equivalent to calling:
|
||
|
||
|
||
cl_add (TY_CLEANUP_ALLOC, p) ;
|
||
Returns an index number which identifies the newly added item in the cleanup list.
|
||
|
||
|
||
The function may call p_leave (E_GEN_NOMEMOoRY) , but not until after the item has been added to the
|
||
cleanup list.
|
||
|
||
|
||
cl_add_shared Add a shared allocated cell
|
||
INT cl_add_shared (VOID *p);
|
||
|
||
Add a shared allocated heap cell, with handle p, to the cleanup list.
|
||
|
||
Calling this function is equivalent to calling:
|
||
|
||
|
||
cl_add(TY_CLEANUP_SHARED, p) ;
|
||
|
||
|
||
Returns an index number which identifies the newly added item in the cleanup list.
|
||
|
||
|
||
The function may call p_leave (E_GEN_NOMEMOoRY) , but not until after the item has been added to the
|
||
cleanup list.
|
||
|
||
|
||
cl_add_dyl Add a DYL
|
||
INT cl_add_dyl(VOID *p);
|
||
|
||
Add a DYL, with handle p, to the cleanup list.
|
||
|
||
Calling this function is equivalent to calling:
|
||
|
||
|
||
cl_add (TY_CLEANUP_DYL, p) ;
|
||
|
||
|
||
Returns an index number which identifies the newly added item in the cleanup list.
|
||
|
||
|
||
The function may call p_leave (E_GEN_NOMEMOoRY) , but not until after the item has been added to the
|
||
cleanup list.
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
cl_remove Remove an item
|
||
|
||
|
||
VOID cl_remove (INT num);
|
||
|
||
|
||
Remove the item specified by num (as returned by an earlier cL_app message or a call to one of the cl_add
|
||
convenience functions) from the cleanup list without cleaning up its associated resource(s).
|
||
|
||
|
||
The item is removed by setting its type to Ty_cLEANuP_vorp. No memory is freed.
|
||
Calling this function is equivalent to:
|
||
|
||
|
||
p_send3 (w_am—>appman.clean, O_CL_REMOVE, num) ;
|
||
|
||
|
||
cl_clean_item Delete an item
|
||
|
||
|
||
VOID cl_clean_item(INT num);
|
||
|
||
|
||
Clean up the resource(s) associated with item num (as returned by an earlier cL_app message or a call to
|
||
one of the c1_add convenience functions) and remove the item from the cleanup list.
|
||
|
||
|
||
No allocated memory associated with the cleanup list's array is freed but the item's type is set to
|
||
TY_CLEANUP_vorp So that it is available for re-use.
|
||
|
||
|
||
Calling this function is equivalent to:
|
||
|
||
|
||
p_send3 (w_am—->appman.clean, O_CL_CLEAN_ITEM, num) ;
|
||
|
||
|
||
CHAPTER 10
|
||
|
||
|
||
THE APPMAN APPLICATION MANAGER CLASS
|
||
|
||
|
||
APPMAN
|
||
|
||
|
||
clean
|
||
system
|
||
rcb
|
||
sxrcb
|
||
ipcs
|
||
task
|
||
stop
|
||
nrid
|
||
err
|
||
sparel
|
||
spare2
|
||
|
||
|
||
am_init
|
||
|
||
am_start
|
||
|
||
am_stop
|
||
am_add_task
|
||
am_wait
|
||
am_load_resource
|
||
am_load_res_buf
|
||
|
||
|
||
am_rscname
|
||
|
||
|
||
am_notify
|
||
|
||
|
||
am_notifyerr
|
||
am_clean_up
|
||
am_onlyone
|
||
am_findimg
|
||
|
||
|
||
am_change_pri
|
||
|
||
|
||
The main function of the application manager class appman is to provide an application's central logic for
|
||
scheduling the processing of events which may derive from more than one source. As such, it is
|
||
fundamental to the operation of a SIBO application, providing the basic support for a multi-threaded
|
||
approach to the processing of events from different sources (such as keypresses, the receipt of data from a
|
||
serial port and the expiry of timers).
|
||
|
||
|
||
In addition, the application manager supplies some general utilities, including methods to access resources
|
||
held in resource files, together with some basic error handling and notification services.
|
||
|
||
|
||
An application process almost invariably creates an instance of the application manager or, more
|
||
commonly, an instance of a user interface subclass of the application manager (for example, HwImman - see
|
||
the HWIM Reference manual). This instance normally remains in existence for the lifetime of the
|
||
application process.
|
||
|
||
|
||
The reserved static w_am is intended to be used to store the handle of an application's application manager,
|
||
making its methods accessible from any part of the application code.
|
||
|
||
|
||
Each of the events that are scheduled by appman is represented by an active object, i.e. an instance of a
|
||
subclass of active. The application manager maintains a queue, in priority order, of instances of active
|
||
objects and the am_start method schedules processing between them in a non pre-emptive way.
|
||
|
||
|
||
10-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
For example, an application which is printing could have the following structure:
|
||
|
||
|
||
Ys
|
||
|
||
|
||
where the application manager (AM) holds a queue of three active objects, WS, PR and TI, representing:
|
||
e the window server (WS)
|
||
e aprinter channel (e.g. a serial port) (PR)
|
||
e an asynchronous timer (TI)
|
||
|
||
|
||
In this example, printing is performed by making a write request on the printer active object and a
|
||
time-out request on the timer active object. (Note that, in general, there will also be an outstanding event
|
||
read request on the window server active object.)
|
||
|
||
|
||
The application manager waits for an event which, in this case, will be the completion of any one of the
|
||
requests on the three active objects. When an event occurs, the application manager scans its active object
|
||
queue to determine which active object has a completed request and is prepared to run. The application
|
||
manager will then send an ao_RuN message to the appropriate active object.
|
||
|
||
|
||
If, in our example, the printer write request completes, the printer active object will be sent an ao_RUN
|
||
message. The printer's ao_run method will typically cancel the timer's time-out request and then repeat its
|
||
own write request and the timer's time-out request, to continue printing. Alternatively, if the time-out
|
||
expires, the timer active object will be sent an ao_RuN message. The timer's ao_run method will abandon
|
||
printing by cancelling the write request on the printer active object.
|
||
|
||
|
||
A window server read event may complete at any point in the printing process - for example, to redraw a
|
||
window or to indicate loss of foreground. In this case the window server active object will receive an
|
||
AO_RUN message and the processing of the window server event is automatically interleaved with the
|
||
processing of the write and time-out events but note that the processing of a write or a timeout event
|
||
cannot be interrupted to handle a window server event.
|
||
|
||
|
||
Active object priorities
|
||
|
||
|
||
The application manager's queue of active objects is maintained, and scanned, in priority order. The
|
||
priority is a signed value, so that the default value of zero is in the middle of the range. The range of
|
||
predefined priorities is given in the Active Objects chapter of this manual.
|
||
|
||
|
||
If more than one active object has generated an event, the first task in the queue is given absolute priority
|
||
- a task at the end of the queue only runs when all earlier tasks are not prepared to run. It is fundamental
|
||
to the scheduling process to note that:
|
||
|
||
|
||
e the events which signal the completion of requests do not necessarily occur in the order in which
|
||
the requests were made
|
||
|
||
|
||
e the active objects are not necessarily given an opportunity to run in the order of completion of the
|
||
corresponding requests - if more than one request has completed, the scheduling mechanism will
|
||
give the object with the highest priority the first opportunity to run.
|
||
|
||
|
||
However, each active object which makes a request will, of course, eventually receive an invitation to run
|
||
at some time following the completion of its request.
|
||
|
||
|
||
Once the application manager has sent an ao_RUN message to an active object, no other active object can
|
||
be given an opportunity to run until the processing of the ao_RuN message is complete and the ao_run
|
||
method has returned. The application manager has no means of preempting the current active object
|
||
(contrast this with the EPOC operating system in which scheduling is preemptive). If the processing of an
|
||
event takes an extended time to perform, all sources of events are blocked for that period of time and this
|
||
may reduce the perceived quality of the application. In particular, the processing of user input (seen as an
|
||
event from the window server) is delayed - the application temporarily goes deaf. A technique for coping
|
||
with this situation is discussed in the Idle Objects and the AIDLE Class chapter of this manual.
|
||
|
||
|
||
10-2
|
||
|
||
|
||
10 THE APPMAN APPLICATION MANAGER CLASS
|
||
|
||
|
||
Active object scheduling
|
||
|
||
|
||
APPMAN'S active object scheduling is a complex process, requiring close cooperation between appman and
|
||
the active objects in its queue. During the process, appman reads and modifies property elements of the
|
||
active objects. It is, therefore, not possible to discuss the scheduling process without making some
|
||
reference to the behaviour of active objects. Perhaps the clearest approach is to consider what qualifies an
|
||
active object to be offered a chance to run.
|
||
|
||
|
||
The first requirement is that it must have made a request to be run, usually by execution of its ao_queue
|
||
method. At this point it will have triggered a sequence which will eventually result in an event being
|
||
detected by appman. appman detects an event by calling p_iowait which returns when p_iosignal is
|
||
called.! The ao_queue method will normally trigger a p_iosignal by making an asynchronous request,
|
||
during which the active.stat field is usually set to —_FILE_PENDING (but see the exception discussed
|
||
below, under the heading The ao_run return value). The making of a request is indicated by the active
|
||
object changing state, from inactive to active (the active.isactive field changes from FaLsE to TRUE).
|
||
|
||
|
||
The later completion of the asynchronous request results in active.stat being set to a value other than
|
||
E_FILE_PENDING.
|
||
|
||
|
||
APpPMaN detects an event by the receipt of a signal on the I/O semaphore of its process. At this point the
|
||
application manager scans, in priority order, all active objects in its queue. If, in the property of an active
|
||
object, active.isactive is set to TRUE, the value of active.stat is examined. If this is set to any value
|
||
other than &_FILE_PENDING the active object is assumed to be prepared to consume the event and is sent
|
||
an AO_RUN message. Normally, the active object confirms that it has consumed the event (signal) by
|
||
returning the value RUN_ACTIVE_USED (see below, under the heading The ao_run return value, for
|
||
exceptions).
|
||
|
||
|
||
If an active object confirms that it has consumed the event, the application manager scheduling loop waits
|
||
for the next event, otherwise it continues looking for an active object that can consume the event. The fatal
|
||
condition, known as stray signal death, occurs if the application manager reaches the end of its list before
|
||
any active object consumes the event. In this situation the application manager calls
|
||
|
||
p_panic (P_PANIC_APPMAN_1). (This panic has the value 143.)
|
||
|
||
|
||
(For further details of asynchronous processes, see the Asynchronous Requests and Semaphores chapter in
|
||
the PLIB Reference manual.)
|
||
|
||
|
||
Note that appman reads an active object's active.isactive and active.stat property fields for reasons of
|
||
efficiency. It avoids the duplication of the tests of these fields in the ao_run method of each active object
|
||
and, more importantly, executes more efficiently since messages are not sent to active objects that are not
|
||
prepared to run.
|
||
|
||
|
||
The ao_run return value
|
||
|
||
|
||
Normally, an active object will represent a source of events of a single type. According to the above
|
||
description of the scheduling mechanism, the active object will not be sent an ao_Run message unless the
|
||
corresponding asynchronous event has completed. In consequence, the ac_run method of such an active
|
||
object can only ever return the value RUN_ACTIVE_USED.
|
||
|
||
|
||
For largely historical reasons an ao_run method may return RUN_ACTIVE_UNUSED to indicate that it has not
|
||
consumed the event. This could, for example, be of use where a single active object is used to represent
|
||
two or more related event sources of different types, for example, serial port reads and writes.
|
||
|
||
|
||
Such an active object would need to maintain a separate status word (in its property) for each type of
|
||
asynchronous request, leaving active.stat with a permanent zero value. It would then be liable to
|
||
receive an AO_RUN message at any time that active.isactive iS TRUE, regardless of the completion status
|
||
of any of its outstanding asynchronous requests. The ao_run method should only return
|
||
RUN_ACTIVE_UNUSED if none of its outstanding requests have completed.
|
||
|
||
|
||
This technique, although relatively simple to implement, is inefficient if the application contains other
|
||
active objects of equal or lower priority. In such a situation the active object will, in general, be sent a
|
||
number of ‘unnecessary’ Ao_RUN messages. From an architectural point of view, and in the interests of
|
||
efficient execution, it is better to implement the handling of multiple event sources by using a separate
|
||
active object for each event source. Each active object will then only be sent an ao_RuN message when its
|
||
corresponding outstanding request has completed (and will always return the value RUN_ACTIVE_USED).
|
||
|
||
|
||
! The call to p_iosignal is thus the event source.
|
||
|
||
|
||
10-3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Precursors
|
||
|
||
The reader is assumed to understand:
|
||
e the PLIB/EPOC I/O system, waits, signals and semaphores.
|
||
e the requirements of an event-driven system.
|
||
e =the p_enter and p_leave error handling services.
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
“—
|
||
|
||
|
||
/ —
|
||
¢ appman
|
||
¢ cleanup =.
|
||
x ) 7 system /
|
||
kg. gre 5 Sas es = ae
|
||
(oa Se Se
|
||
y tscfile / ¢ pes /
|
||
~~ ) S _)
|
||
i oe ae
|
||
|
||
|
||
APPMAN may optionally reference (use) one or more of the CLEANUP, RSCFILE, IPcs and system classes.
|
||
Class definition
|
||
Defined in sub-category file appman.cl (generated header file appman.g).
|
||
|
||
|
||
CLASS appman = root
|
||
|
||
|
||
Application manager -— schedules attached active objects
|
||
{
|
||
ADD am_init Initialise task queue
|
||
ADD am_start Start a scheduling loop
|
||
ADD am_stop Exit one level of the scheduling loop
|
||
ADD am_add_task Insert active object into task queue
|
||
ADD am_wait=p_iowait Wait for the next signal
|
||
ADD am_load_resource Load a resource file record into memory
|
||
ADD am_load_res_buf Load a resource file record into buf supplied
|
||
ADD am_rscname Supply a resource file name at initialisation
|
||
ADD am_notify Notify user
|
||
ADD am_notifyerr Notify user of error
|
||
ADD am_clean_up Clean all logged objects then do an abrun
|
||
ADD am_onlyone Called when the only one check fails
|
||
ADD am_findimg Re-find the image if the pack is moved
|
||
ADD am_change_pri Change the priority of an active object
|
||
CONSTANTS
|
||
{
|
||
FLG_APPMAN_CLEAN Ox01 Create a cleanup list component
|
||
FLG_APPMAN_ SYSTEM 0x02 Create a system configuration component
|
||
FLG_APPMAN_RSCFILE 0x04 Create a resource file component
|
||
FLG_APPMAN_SRSCFILE 0x08 Create a system resource file component
|
||
FLG_APPMAN_IPCS Ox10 Create an ipcs component
|
||
FLG_APPMAN_ONLYONE 0x20 Fail if same process already exists
|
||
FLG_APPMAN_NODBG 0x40 Don't grope for dbg.dyl if set
|
||
RUN_ACTIVE_UNUSED 0 Signal not used
|
||
RUN_ACTIVE_USED 1 Signal used
|
||
ERR_APPMAN_APPL =512 Base for application specific leaves
|
||
}
|
||
PROPERTY 5
|
||
{
|
||
PR_CLEANUP *clean; cleanup list for leaves
|
||
PR_SYSTEM *system; system configuration object
|
||
PR_RSCFILE *rcb; application resource file
|
||
PR_RSCFILE *srcb; system resource file
|
||
PR_IPCS *ipcs; ipcs object
|
||
P_QUE task; queue header
|
||
UWORD stop; start level counter
|
||
WORD nrid; context message rid for notify
|
||
WORD err; abrun error
|
||
UBYTE *sparel; Spare for future expansion.
|
||
UBYTE *spare2; Spare for future expansion.
|
||
|
||
|
||
}
|
||
|
||
|
||
10-4
|
||
|
||
|
||
Property
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
|
||
|
||
appman.
|
||
appman.
|
||
|
||
|
||
clean
|
||
|
||
|
||
system
|
||
|
||
|
||
rcb
|
||
|
||
|
||
sxrcb
|
||
|
||
|
||
ipcs
|
||
|
||
|
||
task
|
||
|
||
|
||
stop
|
||
|
||
|
||
nrid
|
||
|
||
|
||
err
|
||
|
||
|
||
sparel
|
||
spare2
|
||
|
||
|
||
10 THE APPMAN APPLICATION MANAGER CLASS
|
||
|
||
|
||
Contains the handle of the created cLzanup object if the
|
||
FLG_APPMAN_CLEAN flag was specified to am_init. The cLzanup object
|
||
handle is used when an active object's ac_run method leaves with error.
|
||
All applications will normally create a cLEanup object. This field should
|
||
be treated as read only by all objects.
|
||
|
||
|
||
Contains the handle of the created system configuration object if the
|
||
FLG_APPMAN_SYSTEM flag was specified to am_init. This field should be
|
||
treated as read only by all objects.
|
||
|
||
|
||
Contains the handle of the created application resource file Rscr ILE object
|
||
if the FLG_APPMAN_RSCFILE flag was specified to am_init. This object is
|
||
used in the am_load_resource and am_load_res_buf methods, provided
|
||
the specified resource id is positive. This field should be treated as read
|
||
only by all objects. Note that rscriLe objects require the use of the
|
||
application manager's cLEANUP object.
|
||
|
||
|
||
Contains the handle of the created system resource file Rscr1LE object if
|
||
the FLG_APPMAN_SRSCFILE flag was specified to am_init. This object is
|
||
used in am_load_resource and am_load_res_buf methods if the specified
|
||
resource id is negative. This field should be treated as read only by all
|
||
objects. Note that rscrILE objects require the use of the application
|
||
manager's CLEANUP object.
|
||
|
||
|
||
Contains the handle of the created 1pcs object if the rLG_APPMAN_IPCS
|
||
flag was specified to am_init. This field should be treated as read only by
|
||
all objects.
|
||
|
||
|
||
This is the head of the active object task queue. All active objects are
|
||
inserted into this queue when they send the application manager an
|
||
AM_ADD_TASK message. The queue is maintained in priority order. Note
|
||
that if an active object wishes to change its priority it should send appman
|
||
an AM_CHANGE_PRI message; just changing the priority property field is
|
||
not sufficient. This field should not be accessed by any subclass.
|
||
|
||
|
||
Maintains the current level of active object event scheduling, as set by the
|
||
am_start and am_stop methods. This field should not be accessed by any
|
||
subclass.
|
||
|
||
|
||
This field is intended to be used by applications to store a resource id to be
|
||
used in reporting errors. The idea is that this resource id changes as the
|
||
execution of code progresses, the id providing a context of where the
|
||
error(s) are occurring. appMan makes no use of this variable itself, but it is
|
||
used by ACTIVE’s ao_abrun method.
|
||
|
||
|
||
Contains the error returned by the ao_run method of an object. The error
|
||
number is placed there by the am_clean_up code before the ao_abrun
|
||
method is called. This allows the error to be more accessible than if it
|
||
were just passed as a parameter, and also reduces stack build up.
|
||
|
||
|
||
Reserved for future expansion.
|
||
|
||
|
||
APPMAN Methods
|
||
AM_INIT
|
||
|
||
|
||
VOID am_init (UINT flags);
|
||
|
||
|
||
Initialise
|
||
|
||
|
||
Initialise the task queue and create a series of objects as determined by flags which should contain a
|
||
combination of the flag values listed below.
|
||
|
||
|
||
If an error is encountered during initialisation p_1leave is called with the appropriate error. If the
|
||
initialisation fails, an application must assume that none of the requested objects have been created. In
|
||
particular, no resource files will have been opened and hence the application can only exit, without
|
||
attempting to use any resource data.
|
||
|
||
|
||
10-5
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
The following descriptions of the various flag values make reference to a number of other object classes.
|
||
For more information on any of these classes, see the appropriate section of this manual.
|
||
|
||
|
||
FLG_APPMAN_CLEAN
|
||
|
||
|
||
FLG_APPMAN_SYSTEM
|
||
|
||
|
||
FLG_APPMAN_RSCFILE
|
||
|
||
|
||
FLG_APPMAN_SRSCFILE
|
||
|
||
|
||
FLG_APPMAN_IPCS
|
||
|
||
|
||
FLG_APPMAN_ONLYONE
|
||
|
||
|
||
FLG_APPMAN_NODBG
|
||
|
||
|
||
© AM_WAIT
|
||
|
||
|
||
VOID am_wait (VOID)
|
||
|
||
|
||
This flag causes an instance of the cLEanup class to be created and initialised
|
||
with a granularity of 8. This is used to lodge items that must be 'cleaned up'
|
||
on error.
|
||
|
||
|
||
This flag causes an instance of the system class to be created and initialised
|
||
(see the System Services chapter). This is used to obtain system-wide
|
||
information.
|
||
|
||
|
||
This flag causes an instance of the rscFILE class to be created to provide
|
||
access to the application resource file (see the Resource Files chapter). The
|
||
name of the resource file is generated by the am_rscname method, which
|
||
should be subclassed if a different name is required. Note that the rscriLE
|
||
class requires the presence of an instance of the cLzanup class, so this flag
|
||
must always be accompanied by rLG_APPMAN_CLEAN.
|
||
|
||
|
||
This flag causes an instance of the rscFrILz class to be created, to provide
|
||
access to the system resource file (see the Resource Files chapter). Note that
|
||
the rscri1Le class requires the presence of an instance of the cLEanup class,
|
||
so this flag must always be accompanied by rLG_APPMAN_CLEAN.
|
||
|
||
|
||
This flag causes an instance of the 1pcs class to be created and initialised
|
||
with a maximum message size of 8 bytes, in a queue of length 4 (see the
|
||
Inter-process Communication chapter). If this is insufficient then the
|
||
application should not use this flag, but should explicitly create its own 1pcs
|
||
object.
|
||
|
||
|
||
This flag should be set if there must be only one process of this type running
|
||
at any one time. It is, for example, set for Alarms, Link and the System
|
||
process.
|
||
|
||
|
||
If this flag is set and another process exists with the same name as the one
|
||
now being run, appman sends itself an am_ONLYONE message, passing the
|
||
process id of the other process.
|
||
|
||
|
||
In the absence of Psion's internal test and debug library, dbg.dyl, this flag
|
||
has no effect. If this flag is clear and dbg.dy1 is present in the appropriate
|
||
directory, a debug object is created to run test procedures and display various
|
||
items of debug information for the application.
|
||
|
||
|
||
Wait on I/O semaphore
|
||
|
||
|
||
Waits on the I/O semaphore by calling p_iowait.
|
||
|
||
|
||
When an event occurs, it signals the I/O semaphore which causes p_iowait, and hence am_wait, to return.
|
||
|
||
|
||
AM_START
|
||
|
||
|
||
VOID am_start (VOID)
|
||
|
||
|
||
Start scheduler
|
||
|
||
|
||
Start a new level of the application manager active object event scheduler. This method normally does not
|
||
return until the application manager receives an AM_STOP message.
|
||
|
||
|
||
The code of this method is presented below, since it is crucial to the understanding of the application
|
||
manager's active object scheduling mechanism.
|
||
|
||
|
||
10 - 6
|
||
|
||
|
||
10 THE APPMAN APPLICATION MANAGER CLASS
|
||
|
||
|
||
LOCAL_C RunTask(FAST PR_ACTIVE *htask)
|
||
|
||
|
||
{
|
||
INT ret;
|
||
|
||
|
||
htask->active.isactive=FALSE;
|
||
|
||
ret=p_send2 (htask,O_AO_RUN) ;
|
||
|
||
if (ret==RUN_ACTIVE_UNUSED)
|
||
htask->active.isactive=TRUE;
|
||
|
||
return (ret);
|
||
|
||
|
||
}
|
||
|
||
|
||
LOCAL_C RunCleanupAbrun(PR_APPMAN *self,INT err,VOID *htask)
|
||
/*
|
||
Enterable shell
|
||
e/.
|
||
{
|
||
p_send4 (self,O_AM_CLEAN_UP,err,htask) ;
|
||
return (0);
|
||
|
||
|
||
}
|
||
|
||
|
||
METHOD VOID appman_am_start (PR_APPMAN *self)
|
||
/*
|
||
Start the basic loop to get a message from the server.
|
||
May be called recursively for modal interaction.
|
||
%/
|
||
{
|
||
INT stop, ret, abret;
|
||
FAST P_QUE *pt;
|
||
FAST PR_ACTIVE *htask;
|
||
|
||
|
||
stop=(++self-—>appman.stop);
|
||
if (self->appman.clean)
|
||
p_send3 (self-—>appman.clean, O_CL_SET_LEVEL, stop) ;
|
||
do
|
||
{
|
||
p_send2(self,O_AM WAIT); /* wait for next event */
|
||
for (pt=self->appman.task.next;;pt=pt—>next)
|
||
{ /* find a task to run */
|
||
if (pt==&self—>appman.task)
|
||
p_panic(P_PANIC_P_APPMAN_1); /* stray signal */
|
||
htask=(PR_ACTIVE *) (((UBYTE *)pt)-sizeof(PR_ROOT) );
|
||
if (htask->active.isactive && htask->active.stat!=E_FILE_PENDING)
|
||
{
|
||
abret=0;
|
||
if ((ret=p_enter2 (RunTask,htask))<0) /* p_leave(err) called */
|
||
{
|
||
abret=p_enter4 (RunCleanupAbrun, self, ret, htask) ;
|
||
if (abret)
|
||
self-—>appman.stop-—;
|
||
|
||
|
||
}
|
||
if (ret !=RUN_ACTIVE_UNUSED)
|
||
break;
|
||
|
||
|
||
}
|
||
} while (self-—>appman.stop==stop) ;
|
||
if (self->appman.clean)
|
||
{
|
||
p_send2 (self-—>appman.clean, O_CL_CLEAN_LEVEL) ;
|
||
p_send3 (self-—>appman.clean, O_CL_SET_LEVEL, stop-1) ;
|
||
}
|
||
if (abret)
|
||
p_leave(abret); /* allow +ve 'errors' */
|
||
|
||
|
||
}
|
||
|
||
|
||
On entry, appman. stop is incremented. Provided appman.clean is non-zero, the cLEANUP object is sent a
|
||
CL_SET_LEVEL message to set its level to the new value of appman. stop.
|
||
|
||
|
||
The scheduler waits for an event by sending itself an am_wart message. On return, all objects that are
|
||
currently active (active.isactive Set to TRUE) have their completion status words (active.stat)
|
||
checked. If the completion status word is not E_FILE_PENDING the object is sent an ao_RUN message.
|
||
|
||
|
||
10-7
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Assuming that there are no errors, if the object does not consume the event it must return
|
||
RUN_ACTIVE_UNUSED, Otherwise it returns any other value, normally returning RUN_ACTIVE_USED.
|
||
|
||
|
||
If the list of active objects is exhausted without the event being consumed, the scheduling loop calls
|
||
p_panic (P_PANIC_APPMAN_1), indicating the stray signal death condition.
|
||
|
||
|
||
Before sending the ao_run message, the application manager sets the active object's active.isactive to
|
||
FALSE. If the object returns RUN_ACTIVE_UNUSED, active.isactive Is set back to TRUE since the object
|
||
must still be left in the active state if it does not consume the event. If the active object leaves with an
|
||
error, as described below, the TRuz value is not written to active.isactive. (Note that changing the value
|
||
of active.isactive is a code-saving service, avoiding the duplication of code in each active object.)
|
||
|
||
|
||
Any error in the ao_run method is expected to result in p_leave being called. The ao_Run message is sent
|
||
under the protection of a p_enter which catches any p_leave error calls. If an active object calls p_1eave
|
||
within its ac_run method the application manager will receive an error (negative) return value and will
|
||
then send an am_cLEAN_UP message, passing the error that was detected and the handle of the active object
|
||
that called p_ieave.
|
||
|
||
|
||
The am_cLEAN_upP message is also sent under the protection of a p_enter and any non-zero return value
|
||
(representing a p_leave exception in the error handling code) is stored for later use. Note that this will
|
||
cause the current level of event scheduling to terminate, with the error being propagated to the previous
|
||
level. The technique of calling p_1eave within the error handling code should therefore only be used with
|
||
extreme caution.
|
||
|
||
|
||
Note that an ao_run method is free to terminate its processing prematurely by calling p_leave with a zero
|
||
or positive argument - a preferred form of the call is p_leave (RUN_ACTIVE_USED). Such termination will
|
||
not trigger the error reporting and recovery mechanism and may be considered equivalent to a normal
|
||
termination that returns RUN_ACTIVE_USED.
|
||
|
||
|
||
Once an object consumes the signal, by returning a value other than RUN_ACTIVE_UNUSED from its ao_run
|
||
method, no more objects are polled. At this point the am_start method normally loops back to send itself
|
||
another am_wAIT message to wait for the next event.
|
||
|
||
|
||
The exceptions to this are:
|
||
e if an active object has sent an aM_sTop message in its ao_run method
|
||
e if a non-zero return value resulted from the am_cLEAN_UP message.
|
||
|
||
|
||
In either case appman. stop will have been decremented. On completion of the processing of the current
|
||
event, the am_sTart method returns, exiting one level of scheduling.
|
||
|
||
|
||
Before returning, the application manager's cLEaNuP object (if it exists) is sent a CL_CLEAN_LEVEL
|
||
message, to discard all items still in the cleanup list at the current level. It is then sent a cL_SET_LEVEL
|
||
message to adjust it to the new (lower) scheduling level. If a non-zero value resulted from the
|
||
AM_CLEAN_UP message, p_leave Is called, passing this value, to propagate the exception generated in the
|
||
error handling code to the previous level of scheduling.
|
||
|
||
|
||
The application manager active object event scheduler is re-entrant. Thus the ao_run method of an active
|
||
object can send the application manager an aM_sTART message to enter a further level of scheduling.
|
||
Normally, the active object which sends the am_start message will, at that time, have active.isactive
|
||
set to FALSE (by the application manager, before it sends the ao_RuN message) and will therefore not
|
||
receive any further ao_ruN messages until an amM_sTop message is sent. Events occurring under other
|
||
active objects in the application manager's queue will, however, continue to be processed as normal. An
|
||
important example of such use is when a modal dialog box is being run from a menu selection.
|
||
|
||
|
||
There is a great temptation to use this technique to implement any synchronous sequence of actions by
|
||
means of an active object whose initialisation method, say, sends an ao_QuEUE message and then sends the
|
||
application manager an am_sTart message. This technique should be used with care, particularly when
|
||
recovery from an error involves items on the cleanup list.
|
||
|
||
|
||
Because of the different level, the items that are cleaned will be different for an error that occurs before an
|
||
AM_START message (for example, during an initialisation phase) from the items that are cleaned up after
|
||
(say, within an ao_run method). It may be advisable to transfer any part of the initialisation that can fail
|
||
into an ao_run method and execute it under the control of a state variable in the object's property, the first
|
||
time that the ao_run method is called. This also resolves any problem as to whether the error recovery
|
||
code should or should not send an am_stop message. The following general code briefly illustrates the
|
||
principle of implementing such an active object sequencer:
|
||
|
||
|
||
10-8
|
||
|
||
|
||
10 THE APPMAN APPLICATION MANAGER CLASS
|
||
|
||
|
||
GLREF_D PR_APPMAN *w_am;
|
||
|
||
|
||
VOID sequence_ao_init (PR_SEQUENCE *self)
|
||
{
|
||
self—>active.priority=PRIORITY_ACTIVE_COMPUTE;
|
||
p_send3 (w_am, O_AM_ADD_TASK, self) ;
|
||
self—>active.isactive=TRUE;
|
||
|
||
|
||
p_iosignal();
|
||
p_send2 (w_am,O_AM_START) ;
|
||
}
|
||
|
||
|
||
sequence_ao_run(PR_SEQUENCE *self)
|
||
{
|
||
switch (self-—>sequence.state_variable)
|
||
{
|
||
case 0:
|
||
/* initialise */
|
||
break;
|
||
case 1:
|
||
/* action 1 */
|
||
break;
|
||
case 2:
|
||
|
||
|
||
case 5:
|
||
p_send2 (w_am,O_AM_STOP) ;
|
||
return (RUN_ACTIVE_USED) ;
|
||
}
|
||
|
||
|
||
self—>sequence.state_variablet=1;
|
||
|
||
|
||
self—->active.isactive=TRUE;
|
||
p_iosignal();
|
||
|
||
return (RUN_ACTIVE_USED) ;
|
||
|
||
}
|
||
|
||
|
||
& AM _STOP Stop scheduler
|
||
|
||
|
||
VOID am_stop (VOID)
|
||
|
||
|
||
Stop the current level of the active object event scheduling loop, by decrementing appman. stop. This
|
||
causes the most nested am_start to return after handling of the current event is complete.
|
||
|
||
|
||
& AM_ADD_TASK Add a task
|
||
|
||
|
||
VOID am_add_task(PR_ACTIVE *hand) ;
|
||
|
||
|
||
Add an initialised active object to the task queue, in priority order, as determined by the active object's
|
||
active.priority field.
|
||
|
||
|
||
The item is added to the list immediately following all existing items with the same (or higher) priority.
|
||
|
||
|
||
AM_LOAD_ RESOURCE Load a resource
|
||
|
||
|
||
INT am_load_resource(INT resid, UBYTE **ppdata) ;
|
||
Allocate a buffer and load into it the resource with id resia from the appropriate resource file.
|
||
|
||
|
||
A negative resid indicates that the resource is to be found in the system resource file, with an id equal to
|
||
the absolute value of resid. Otherwise it is assumed that the resource is to be found in the application
|
||
resource file.
|
||
|
||
|
||
If you wish to access the system resource file you must have passed the FLG_APPMAN_SRSCFILE flag to the
|
||
am_init method. It is recommended, but not strictly essential (because the am_load_resource method will
|
||
search for and open the application resource file if it is not already open) that you pass the
|
||
FLG_APPMAN_RSCFILE flag to the am_init method if you wish to access the application resource file.
|
||
|
||
|
||
If the appropriate rscFILE object exists, the resource is loaded by sending an rs_READ message to the
|
||
appropriate RSCFILE object, under the protection of p_enter. If the loading of the resource fails due to out
|
||
of memory then p_leave (E_GEN_NoMEmoRY) is called.
|
||
|
||
|
||
10-9
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Any other error when attempting to read an application resource, including the absence of the application
|
||
resource RSCFILE object, is assumed to be due to the removal of the application resource file. (It is
|
||
assumed that only the application resource file can be removed since the system resource file is in the
|
||
ROM.) If the application manager's application RscrILE component exists, it is destroyed. An attempt is
|
||
then made to locate the resource file by sending am_Finp1mc and am_RscnameE messages. If this is
|
||
successful the RscFILE object is recreated and the file reopened - either of which could fail, calling
|
||
p_leave (E_GEN_NOMEMoRY) - otherwise the method calls p_1eave (Z_FILE_NXIST) . Following this, the
|
||
resource is loaded by sending the appropriate rscrILz object an RS_READ message, which may fail -
|
||
typically by calling p_leave (E_GEN_NOMEMORY) .
|
||
|
||
|
||
The method returns the size of the loaded resource, as returned by the rs_READ message.
|
||
|
||
|
||
AM_LOAD_RES_ BUF Load a resource to a buffer
|
||
|
||
|
||
INT am_load_res_buf (INT resid, UBYTE *pbuf) ;
|
||
Load into the buffer pointed to by pbut the resource with id resia from the appropriate resource file.
|
||
|
||
|
||
A negative resid indicates that the resource is to be found in the system resource file, with an id equal to
|
||
the absolute value of resid. Otherwise it is assumed that the resource is to be found in the application
|
||
resource file.
|
||
|
||
|
||
If you wish to access the system resource file you must have passed the FLG_APPMAN_SRSCFILE flag to the
|
||
am_init method. It is recommended, but not strictly essential (because the am_load_resource method will
|
||
search for and open the application resource file if it is not already open) that you pass the
|
||
FLG_APPMAN_RSCFILE flag to the am_init method if you wish to access the application resource file.
|
||
|
||
|
||
If the appropriate RscFILE object exists, the resource is loaded by sending an rs_READ message to the
|
||
appropriate RSCFILE object, under the protection of p_enter. If the loading of the resource fails due to out
|
||
of memory then p_leave (E_GEN_NoMEMoRY) is called.
|
||
|
||
|
||
Any other error when attempting to read an application resource, including the absence of the application
|
||
resource RSCFILE object, is assumed to be due to the removal of the application resource file. (It is
|
||
assumed that only the application resource file can be removed since the system resource file is in the
|
||
ROM.) If the application manager's application RscrILE component exists, it is destroyed. An attempt is
|
||
then made to locate the resource file by sending am_F1npIMc and am_RscnamE messages. If this is
|
||
successful the RscFILE object is recreated and the file reopened - either of which could fail, calling
|
||
p_leave (E_GEN_NOMEMORY) - otherwise the method calls p_1leave (Z_FILE_NXIST) . Following this, the
|
||
resource is loaded by sending the appropriate rscFrILz object an RS_READ message, which may fail -
|
||
typically by calling p_leave (E_GEN_NOMEMORY) .
|
||
|
||
|
||
The method returns the size of the loaded resource, as returned by the rs_READ_BUF Message.
|
||
|
||
|
||
AM_RSCNAME Generate resource file name
|
||
|
||
|
||
VOID am_rscname(UBYTE *pname) ;
|
||
|
||
|
||
Write to the buffer at *pname (which must be at least p_rnames1zeE bytes long) the default full file
|
||
specification (see the Files chapter of the PLIB Reference manual) of the application resource file.
|
||
|
||
|
||
The name is generated from the application's start-up full file specification, pointed to by the magic static
|
||
DatCommandPtr.
|
||
|
||
|
||
The resource file is assumed to be built into the image file, so that the full file specification is identical to
|
||
that of the image file.
|
||
|
||
|
||
& AM_NOTIFY Display notifier
|
||
|
||
|
||
VOID am_notify(UINT messl, UINT mess2, UWORD *pbut) ;
|
||
Call the p_notify service with text loaded from resource files.
|
||
|
||
|
||
Up to two text messages are specified by the resource ids mess1 and mess2. If pbut is Nutt, the single
|
||
default button 'CONTINUE' (or the non-English equivalent) will be displayed. Otherwise, pbut is
|
||
assumed to point to an array of three resource ids for the three notifier buttons.
|
||
|
||
|
||
All resource ids follow the resource id rules as specified in the description of the am_load_resource
|
||
method. If any id is nunz then no text is loaded for that id.
|
||
|
||
|
||
10 - 10
|
||
|
||
|
||
10 THE APPMAN APPLICATION MANAGER CLASS
|
||
|
||
|
||
Once the resource strings are loaded the p_not ify service is invoked. The allocated space for the resource
|
||
strings is freed after use.
|
||
|
||
|
||
This method will not fail due to lack of memory. If there is not enough memory available to load any of
|
||
the specified resources, the corresponding part of the notification text is not displayed.
|
||
|
||
|
||
& AM_NOTIFYERR Notify an error
|
||
|
||
|
||
VOID am_notifyerr(INT err, UINT messl1,UWORD *pbut) ;
|
||
Call the p_notifyerr service, with text loaded from resource files.
|
||
|
||
|
||
A first line text message is specified by the resource id messi. A second line contains a description of the
|
||
error, as generated by p_errs (err). If pbut is nuLt, the single default button 'CONTINUE' (or the non-
|
||
English equivalent) will be displayed. Otherwise, pbut is assumed to point to an array of three resource
|
||
ids for the three notifier buttons.
|
||
|
||
|
||
All resource ids follow the resource id rules as specified in the description of the am_load_resource
|
||
method. If any id is nunz then no text is loaded for that id.
|
||
|
||
|
||
Once the resource strings are loaded the p_notifyerr service is invoked, which converts the error number
|
||
err into the second line text message. The allocated space for the resource strings is freed after use.
|
||
|
||
|
||
This method will not fail due to lack of memory. If there is not enough memory available to load any of
|
||
the specified resources, the corresponding part of the notification text is not displayed.
|
||
|
||
|
||
AM_CLEAN_UP Clean up resources and report an error
|
||
|
||
|
||
VOID am_clean_up(INT err, UBYTE *htask);
|
||
Provide standard error recovery and reporting for the active object event scheduler.
|
||
|
||
|
||
This method is called from the am_start event scheduler if an active object's ac_run method calls
|
||
p_leave (error). The handle of the active object is in htask and err is the error number passed to
|
||
p_leave.
|
||
|
||
|
||
The value of err is copied to appman.err and if there is a cLEaNupP object it is sent a CL_CLEAN_LEVEL
|
||
message to tidy up all resources added to the cleanup list at this level of event scheduling.
|
||
|
||
|
||
If htask is not NULL, AN AO_ABRUN message Is sent to that object. The ao_abrun method may call p_leave,
|
||
in which case the error will be caught in the am_start method. It will cause the current level event
|
||
scheduling to terminate, the p_leave error being propagated to the next level of scheduling.
|
||
|
||
|
||
This method is supplied in order to facilitate the customising of all, or a particular set of, errors.
|
||
|
||
|
||
Note that the active object which generated the error in its ao_run method is sent an Ao_ABRUN message
|
||
after the sending of the cL_cLEAN_LEVEL message. This means that (unless the am_cleanup method is
|
||
subclassed) the active object must not itself be in the cleanup list at the current level, otherwise it will be
|
||
destroyed before the ao_aBrun message is sent. It is likely, in any practical case, that an active object that
|
||
has been placed in the cleanup list will have been removed before it receives its first ao_RUN Message.
|
||
|
||
|
||
In general, the active object will only be placed in the cleanup list temporarily while other objects are
|
||
being built and resources acquired; in this state of construction, it is unlikely that an application would
|
||
"activate" the active object and risk receiving an Ao_ABRUN Message.
|
||
|
||
|
||
AM_FINDIMG Find application image file
|
||
|
||
|
||
INT am_findimg (VOID) ;
|
||
Relocate the SSD from which the application was run.
|
||
|
||
|
||
It uses the magic static DatCommandPtr, assuming that it points to the current full file specification of the
|
||
application's .img (or .app) file. It looks in all available SSD drives (A and B and, if they exist, C and D).
|
||
If it finds a file with the same name in the directory specified by pat commandPtr it patches the data at
|
||
DatCommandPtr to reflect the new path and returns zero. If no such file can be found £_F1LE_nxist (the
|
||
return value from a p_finfo call) is returned.
|
||
|
||
|
||
Typically this is called when the application wishes to access some information from the SSD from which
|
||
it was run, but finds that the SSD is no longer in that drive. It is used in this way by the
|
||
am_load_resource and am_load_res_buf methods.
|
||
|
||
|
||
10-11
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
AM_ONLYONE Ensure only one copy running
|
||
VOID am_onlyone(UINT pid);
|
||
|
||
|
||
Ensure that a second copy of an application is not launched. This method simply calls
|
||
p_leave (E_FILE_EXIST).
|
||
|
||
|
||
It is called during the am_init method if the rLc_appMaN_oNLyYonE flag was specified and another process
|
||
of the same name is already running.
|
||
|
||
|
||
The Alarm application is an example of a process which should never have more than one copy running.
|
||
|
||
|
||
& AM_CHANGE_PRI Change active object priority
|
||
|
||
|
||
VOID am_change_pri(PR_ACTIVE *pObject, INT priority);
|
||
|
||
|
||
Change the priority of the active object with handle pobject to the value in priority.
|
||
|
||
|
||
The result will be unpredictable if the object is not currently in the application manager's active object
|
||
queue.
|
||
|
||
|
||
The active object is removed from the application manager's active object queue, the new priority is copied
|
||
into active.priority and the object is then re-inserted with the new priority.
|
||
|
||
|
||
10-12
|
||
|
||
|
||
CHAPTER 11
|
||
|
||
|
||
THE ACTIVE CLASS AND ACTIVE OBJECTS
|
||
|
||
|
||
ACTIVE
|
||
|
||
|
||
gq
|
||
priority
|
||
|
||
|
||
isactive
|
||
pcb
|
||
stat
|
||
|
||
|
||
destroy
|
||
ao_init
|
||
ao_cancel
|
||
ao_abrun
|
||
ao_queue
|
||
|
||
|
||
ao_run
|
||
|
||
|
||
The active class provides common behaviour for active objects. An active object may be thought of as an
|
||
event source and is, by definition, any object which has acTIVE as an ancestor in its inheritance tree.
|
||
|
||
|
||
Active objects are fundamental to the operation of event-driven SIBO applications (the overwhelming
|
||
majority of all SIBO applications). In such an application, virtually all processing is performed within the
|
||
ao_run method of some active object or other.
|
||
|
||
|
||
Although it is not formally an abstract class, the acTIveE class must be subclassed to create a useful active
|
||
object. OLIB and HWIM supply a number of subclasses of active for use by applications. In addition, an
|
||
application may define one or more application-specific active object classes.
|
||
|
||
|
||
A typical active object corresponds to an asynchronous channel on one of PLIB's I/O devices. An
|
||
assumption, embodied in acTIve's property, is that only one asynchronous event per active object can be
|
||
outstanding at any one time.
|
||
|
||
|
||
See the Application Manager chapter for further information about active objects and event scheduling.
|
||
|
||
|
||
Note that active objects making asynchronous requests on the file server should subclass FAcTIVE in
|
||
preference to active. See the File Active Objects chapter for further details.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e the appman class, in particular the event scheduling mechanisms.
|
||
e the PLIB/EPOC asynchronous I/O system, waits, signals and semaphores.
|
||
e requirements of an event-driven system.
|
||
|
||
|
||
e =the p_enter and p_leave error handling services.
|
||
|
||
|
||
11-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
The actrve class subclasses root and is defined in the sub-category file appman.cl (with generated header
|
||
file appman.g).
|
||
|
||
|
||
CLASS active root
|
||
Active object superclass for representing event sources
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE destroy Close IO channel and free itself
|
||
ADD ao_init Open IO channel
|
||
ADD ao_cancel Cancel outstanding read request
|
||
ADD ao_abrun Abnormal, p_leave induced, termination of ao_run
|
||
ADD ao_queue Queue request (normally subclassed)
|
||
ADD ao_run Provide an opportunity to run
|
||
CONSTANTS
|
||
{
|
||
! Priorities
|
||
PRIORITY_ACTIVE_POSTER 100
|
||
PRIORITY_ACTIVE_IPCS 80
|
||
PRIORITY_ACTIVE_VOICE 70
|
||
PRIORITY_ACTIVE_WSERV 60
|
||
PRIORITY_ACTIVE_COMMAND 40
|
||
PRIORITY_ACTIVE_SERIAL 20
|
||
PRIORITY_ACTIVE_ALARM 0
|
||
PRIORITY_ACTIVE_FILES -20
|
||
PRIORITY_ACTIVE_REPEATER -40
|
||
PRIORITY_ACTIVE_PRINT -60
|
||
PRIORITY_ACTIVE_COMPUTE -100
|
||
}
|
||
PROPERTY
|
||
{
|
||
P_QUE q; queue header
|
||
BYTE priority; priority compared to other active objects
|
||
UBYTE isactive; TRUE if there is a request pending
|
||
UBYTE *pcb; I/O channel
|
||
WORD stat; I/O completion status
|
||
}
|
||
}
|
||
Property
|
||
active.g Used by the application manager to include an active object in its
|
||
prioritised queue. It should not be accessed other than by the application
|
||
manager and an active object's destroy method.
|
||
active.priority Used to determine the object's position in the application manager's
|
||
prioritised queue. The value, which will normally be one of the priorities
|
||
listed in the acttve class definition, should be set up prior to sending the
|
||
application manager an aM_ADD_TASK message.
|
||
active.isactive Should be set to TRuE when the active object is (or will be, on completion
|
||
of an outstanding asynchronous request - see also active.stat) prepared
|
||
to receive an Ao_RUN message. A common error is to fail to set
|
||
active.isactive to TRUE when an asynchronous request is made. This
|
||
will eventually cause stray signal death, described in the Application
|
||
Manager chapter of this manual. The application manager sets
|
||
active.isactive to FALSE when it sends the ao_RUN message, avoiding
|
||
the need for the ao_run method of each individual active object to clear
|
||
this field.
|
||
active.pcb Normally holds the handle of the device upon which the active object
|
||
makes its I/O requests. Many of the methods supplied by the actrve class
|
||
assume that this is a true I/O channel handle.
|
||
active.stat Normally used as the completion status word for an asynchronous request.
|
||
|
||
|
||
Only if its value is not =_FILE_PENDING will the application manager's
|
||
event scheduling loop send an ao_Run message to this active object
|
||
(active.isactive must also be TRUE).
|
||
|
||
|
||
11-2
|
||
|
||
|
||
11 THE ACTIVE CLASSS AND ACTIVE OBJECTS
|
||
|
||
|
||
ACTIVE methods
|
||
|
||
|
||
J DESTROY Destroy the instance
|
||
|
||
|
||
VOID destroy (VOID)
|
||
|
||
Takes the following actions:
|
||
e sends itself an ao_caNcEL message to cancel any pending asynchronous request
|
||
e removes itself, if necessary, from the application manager's task queue
|
||
|
||
|
||
e closes any I/O channel, whose handle is assumed to be in active.pcb (this is harmless if
|
||
active.pcb is NULL)
|
||
|
||
|
||
e supersends itself a pEsTRoy message.
|
||
|
||
|
||
If a subclass uses active.pcb to contain anything other than an I/O channel handle, it should ensure that
|
||
active.pcb 1s set to nuLL before this method is executed.
|
||
|
||
|
||
AO_INIT Initialise the instance
|
||
VOID ao_init (TEXT *devname, INT mode) ;
|
||
Initialise the active object.
|
||
|
||
|
||
Uses p_open to open a channel to the device specified by devname and mode, writing the channel handle to
|
||
active.pcb. Calls p_leave if there is an error opening the channel.
|
||
|
||
|
||
The object is not added to the application manager's task queue and no other fields in the property are
|
||
changed.
|
||
|
||
|
||
J AO_QUEUE Make a request to run
|
||
|
||
|
||
VOID ao_queue (VOID) ;
|
||
|
||
|
||
Set active.isactive to TRUE and signal the I/O semaphore by calling p_iosigna1 without altering the
|
||
value of active.stat (whose default value is zero). As a result, the object will eventually be sent an
|
||
AO_RUN message by the application manager.
|
||
|
||
|
||
This method is provided for use by idle object subclasses (see Idle Objects and the AIDLE Class). Other
|
||
active objects would normally subclass this method. All subclasses must ensure that the ao_queue method
|
||
sets active.isactive tO TRUE.
|
||
|
||
|
||
J AO CANCEL Cancel a request to run
|
||
|
||
|
||
VOID ao_cancel (VOID)
|
||
Cancel any outstanding asynchronous request.
|
||
Does nothing if active.isactive is not TRUE.
|
||
|
||
|
||
If active.isactive iS TRUE then it is re-set to FALSE. If active.pcb 1S not NULL, it is assumed to be the
|
||
handle of an I/O channel and a p_FcancEL request is made to that channel. Regardless of the value of
|
||
active.pcb, this is followed by a p_waitstat, waiting on active.stat.
|
||
|
||
|
||
The ao_caNcEL message may be received before or after the corresponding request has completed:
|
||
|
||
|
||
e if it is before the completion, the outstanding request is cancelled and the p_waitstat waits for,
|
||
and absorbs the event which signals the completion of the cancel
|
||
|
||
|
||
e if itis after the completion (but before its processing) the p_rcancEL request does not generate its
|
||
own completion event. In this case the p_waitstat consumes the event already generated by the
|
||
completion of the asynchronous request, effectively discarding it.
|
||
|
||
|
||
Note that the completion result placed in active.stat 1s likely to be different in the above two cases, but
|
||
is normally ignored since the status following a cancel is generally not significant.
|
||
|
||
|
||
11-3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Since the destroy method sends an ao_caNncEL message, the active class contains implicit assumptions
|
||
that:
|
||
|
||
|
||
e = the ao_cance1 method will never call p_leave
|
||
|
||
|
||
¢ itis safe to send an ao_caNcEL message at any time, even if there has not been a previous
|
||
AO_QUEUE Message.
|
||
|
||
|
||
These assumptions about the cancel service are certainly true at the PLIB level, where a p_rcanceL does
|
||
not rely on there being an outstanding request (for example P_FREAD or P_FWRITE). They are also true for
|
||
all system-supplied subclasses of active. Subclassers of the active class should ensure that this
|
||
assumption remains true.
|
||
|
||
|
||
Active objects that perform operations on files should subclass ractive (described in the File Active
|
||
Objects chapter) which provides the correct support for a file system cancel service.
|
||
|
||
|
||
The ao_cance1 method provided by active may safely be used by non-I/O subclasses provided they leave
|
||
active.stat at NULL.
|
||
|
||
|
||
AO_ABRUN Handle an error
|
||
|
||
|
||
VOID ao_abrun (VOID);
|
||
Report an error condition arising from a call to p_leave in the object's ao_run method.
|
||
Sends the application manager an aM_NOTIFYERR message:
|
||
|
||
|
||
p_send5 (w_am, O_AM_NOTIFYERR, w_am->appman.err,w_am—>appman.nrid, NULL) ;
|
||
|
||
|
||
and then sets appman.nrid tO NULL.
|
||
|
||
|
||
The application manager has previously set appman.err to contain the error number passed as the
|
||
|
||
|
||
parameter to p_leave, and appman.nrid 1s assumed to be either nut, or an application-specific resource
|
||
id.
|
||
|
||
|
||
The application manager and its property are accessed via the magic static w_am, which is assumed to
|
||
have been initialised (as it is, for example, in the am_init method of the swimman subclass of appman - see
|
||
the HWIM Reference manual).
|
||
|
||
|
||
The ao_aprun method may be subclassed to provide more specific error handling. Note that a
|
||
CL_CLEAN_LEVEL message will have been sent to any application manager cLEaNnup object before the
|
||
AO_ABRUN message is received.
|
||
|
||
|
||
AO_RUN Process an event
|
||
|
||
|
||
INT ao_run (VOID)
|
||
|
||
|
||
A default method which simply returns RuN_ACTIVE_USED, to signal to the application manager that it has
|
||
consumed an event. Most active objects will subclass this method.
|
||
|
||
|
||
An active object will only receive an ao_Run message if active.isactive iS TRUE and active.stat is not
|
||
E_FILE_PENDING. The application manager sets active.isactive to FALSE before sending the ao_RuUN
|
||
message.
|
||
|
||
|
||
11-4
|
||
|
||
|
||
CHAPTER 12
|
||
|
||
|
||
IDLE OBJECTS AND THE AIDLE CLASS
|
||
|
||
|
||
Idle objects
|
||
|
||
|
||
Well-behaved applications should break down long, computationally intensive operations into a sequence
|
||
of smaller sections processed in idle time, so that the application can avoid going deaf to window server
|
||
messages for long periods of time. In other words, these operations should only be allowed to run when no
|
||
other higher priority work is ready to run (e.g. responding to window server messages).
|
||
|
||
|
||
This is normally achieved by using an active object of low priority (usually PRIORITY_ACTIVE_COMPUTE)
|
||
which will only be run when no other active objects have any work to perform. An active object used for
|
||
such a purpose is known as an idle object.
|
||
|
||
|
||
An idle object will typically leave active.stat at a zero value and use the default ac_queue method
|
||
provided by the active class. Its ao_run method is usually subclassed to perform a unit of processing and
|
||
then (provided processing is not yet complete) send itself an ao_QUEUE message.
|
||
|
||
|
||
A partially complete operation may be invalidated by a subsequent event. In such a case the operation
|
||
should be cancelled and restarted. Such use of an idle object is appropriate, for example:
|
||
|
||
|
||
in a text processor word wrapping a line at a time without falling behind in echoing user
|
||
input in the current line.
|
||
|
||
|
||
in a spreadsheet calculating a cell at a time in auto-calculate mode, allowing the user to
|
||
continue to input during the calculation.
|
||
|
||
|
||
An empty idle object - one whose ao_run method does nothing but send itself an ao_QUEVE message - will
|
||
execute its ao_run method several hundred times per second.
|
||
|
||
|
||
AIDLE
|
||
|
||
|
||
ACTIVE
|
||
|
||
|
||
gq
|
||
priority
|
||
|
||
|
||
isactive
|
||
pcb
|
||
stat
|
||
|
||
|
||
destroy
|
||
in
|
||
ao_cancel
|
||
ao_abrun
|
||
ao_queue
|
||
|
||
|
||
aeTFuFn
|
||
|
||
|
||
The arpte class provides the basic functionality of an idle object.
|
||
|
||
|
||
12-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
The supplied ac_run method simply requests the application manager to exit from one level of application
|
||
manager event scheduling by sending the application manager an am_stop message. In this form it may be
|
||
used to pause some operation to allow the processing of other events. This usage, which is illustrated in
|
||
the first example below, can be considered as a means of adding some aspects of idle time processing to
|
||
code which, for one reason or another, is not suitable for implementation as an active object.
|
||
|
||
|
||
A true idle object must subclass the ao_run method to perform the required processing, as described
|
||
above, and as illustrated in the second example.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e =the active class
|
||
e the application manager's event scheduling mechanism
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
fe
|
||
(active /
|
||
= )
|
||
CoS
|
||
|
||
|
||
—
|
||
—
|
||
|
||
|
||
/ aidle /
|
||
ie )
|
||
|
||
|
||
Nee
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file appman.cl (generated header file appman.g).
|
||
|
||
|
||
CLASS aidle active
|
||
Idle active object.
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE ao_init Add itself to active list at low priority
|
||
REPLACE ao_run Send w_am an O_AM_STOP
|
||
}
|
||
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
AIDLE methods
|
||
|
||
|
||
J AO_INIT Initialise
|
||
|
||
|
||
VOID ao_init (VOID)
|
||
|
||
|
||
Set active.priority tO PRIORITY_ACTIVE_COMPUTE and send the application manager an aM_ADD_TASK
|
||
message.
|
||
|
||
|
||
J AO RUN Run
|
||
|
||
|
||
INT ao_run(VOID) ;
|
||
|
||
|
||
Send the application manager an am_stop message and return RUN_ACTIVE_USED.
|
||
|
||
|
||
12-2
|
||
|
||
|
||
12 IDLE OBJECTS AND THE AIDLE CLASS
|
||
|
||
|
||
Ds A nnn _______yz.
|
||
Examples
|
||
|
||
|
||
Pause an operation
|
||
|
||
|
||
Some operations are not suitable for implementation in an active object format. The quicksort algorithm,
|
||
for example, is recursive and therefore dependent on stacked state information. Since it could take an
|
||
extended time to sort the data, some action should be taken to ensure that the calling application remains
|
||
responsive to redraws and user input. A considerable rewrite would, however, be necessary to enable
|
||
quicksort to execute as a sequence of separate calls to an ao_run method.
|
||
|
||
|
||
A more convenient solution in such a case is to insert, at some point which is repeatedly executed, code
|
||
which pauses execution and allows other events (such as redraws) to be processed. The principle is
|
||
illustrated in the following code:
|
||
|
||
|
||
VOID MakeIdle (VOID)
|
||
{
|
||
INT i;
|
||
VOID *aidle;
|
||
|
||
|
||
aidle=f_newsend (CAT_DEMO_OLIB, C_AIDLE, O_AO_INIT);
|
||
for (i=0;i<1000;i++)
|
||
{
|
||
|
||
|
||
p_send2 (aidle, 0O_AO_QUEUE) ;
|
||
p_send2 (w_am,O_AM_START); /* does not return until AIDLE has run */
|
||
|
||
|
||
}
|
||
p_send2 (aidle,O_DESTROY) ;
|
||
|
||
|
||
}
|
||
|
||
|
||
The ao_quruz message is handled at the active level, simply setting active.isactive to TRUE and
|
||
signalling the I/O semaphore. The send of the am_start message will not return until the am_stop
|
||
message is sent by arpLE's ao_run method (which will not run until there are no outstanding events for
|
||
any active object of priority higher than that of arp1z).
|
||
|
||
|
||
Depending on the nature of the process, it may be more appropriate to pause, say, every tenth, or
|
||
hundredth, time round the loop. In other words, it is the responsibility of the process to decide when or
|
||
how often to pause.
|
||
|
||
|
||
Idle time computation
|
||
|
||
|
||
This example illustrates one of the most common forms of idle active object. It is the form that would be
|
||
used, say, to reformat a portion of text, following the insertion or deletion of characters. It includes the
|
||
ability to cancel and restart the operation on receipt of a further event (for example, another keypress)
|
||
which invalidates a partially complete operation.
|
||
|
||
|
||
Note that the ao_run method is subclassed so that no use is made of the functionality of arDLE's ao_run
|
||
method.
|
||
|
||
|
||
CLASS exidle aidle
|
||
example idle object
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE ao_cancel to reset the processing state
|
||
REPLACE ao_run perform a unit of processing
|
||
PROPERTY
|
||
|
||
{
|
||
|
||
WORD counter; records the current processing state
|
||
|
||
|
||
}
|
||
}
|
||
|
||
|
||
METHOD VOID exidle_ao_cancel (PR_EXIDLE *self)
|
||
{
|
||
|
||
|
||
self—>exidle.counter=0;
|
||
p_supersend2 (self,O_AO_CANCEL) ;
|
||
}
|
||
|
||
|
||
12-3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
METHOD INT exidle_ao_run(PR_EXIDLE *self)
|
||
{
|
||
p_printf ("Processing stage %d",self->exidle.counter+t+) ;
|
||
if (self->exidle.counter<3)
|
||
p_send2 (self, O_AO_QUEUE) ;
|
||
return (RUN_ACTIVE USED);
|
||
}
|
||
|
||
|
||
The active object is run as illustrated below, following the action (say, the insertion of a character) which
|
||
necessitates the processing.
|
||
|
||
|
||
GLREF_D PR_EXIDLE *exidle;
|
||
|
||
|
||
p_send2 (exidle,O_AO_CANCEL); /* cancel any partially complete processing */
|
||
p_send2 (exidle,O_AO_QUEUE); /* restart the processing */
|
||
|
||
|
||
The above code fragment assumes that the active object exists for the lifetime of the application; its
|
||
creation and destruction would be handled elsewhere.
|
||
|
||
|
||
If the active object is to have a transient existence, it would normally be created (with the appropriate
|
||
error handling) immediately prior to its use. In this case it would be appropriate for the object to send
|
||
itself a DESTROY message in its ao_run method on completion of the processing.
|
||
|
||
|
||
12-4
|
||
|
||
|
||
CHAPTER 13
|
||
|
||
|
||
TIMER ACTIVE OBJECT CLASSES
|
||
|
||
|
||
This chapter describes the TIMER class and two TIMER subclasses, ANIMATOR and BUZSND.
|
||
|
||
|
||
The Trmer class, although not formally an abstract class, must be subclassed to provide a specific ao_run
|
||
method to process the timer expiry.
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
fe ee
|
||
¢ active /
|
||
|
||
|
||
timer /
|
||
|
||
|
||
a?
|
||
~\.
|
||
|
||
[or Te
|
||
¢ animator/ ~ buzsnd /
|
||
|
||
|
||
- mye )
|
||
|
||
|
||
Ne ad
|
||
|
||
|
||
—~—
|
||
|
||
|
||
C
|
||
fy
|
||
f- —_—~
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e the active class.
|
||
e the PLIB/EPOC timer driver services.
|
||
|
||
|
||
e = for BuzsND, the EPOC sound driver services
|
||
|
||
|
||
13-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TIMER
|
||
|
||
|
||
ACTIVE
|
||
|
||
|
||
gq
|
||
priority
|
||
isactive
|
||
pcb
|
||
|
||
stat
|
||
|
||
|
||
destroy ao_init
|
||
aorinit ao_queue
|
||
ao_cancel tm_qabsolute
|
||
|
||
|
||
ao_abrun
|
||
|
||
|
||
The T1rmer class supplies methods to queue both relative and absolute timers. See the Time, Timers and
|
||
Dates chapter of the PLIB Reference manual for a description of absolute and relative timers and their
|
||
differences.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file timer.cl (generated header file timer.g).
|
||
|
||
|
||
CLASS timer active
|
||
The timer active object
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE ao_init Opens a channel to an asynchronous timer
|
||
REPLACE ao_queue Queues a relative timer
|
||
ADD tm_qgabsolute Queues an absolute timer
|
||
}
|
||
Property
|
||
None.
|
||
|
||
|
||
TIMER methods
|
||
|
||
|
||
AO_INIT Initialise
|
||
|
||
|
||
VOID ao_init (VOID) ;
|
||
|
||
|
||
Open a channel to a timer using the device name "T1m:" by supersending the ao_tnrT message. This uses
|
||
the PLIB p_open function.
|
||
|
||
|
||
The open timer channel handle will be stored in active.pcb if the timer was successfully opened.
|
||
|
||
|
||
Calls p_1eave on error.
|
||
|
||
|
||
J AO_QUEUE Queue (relative)
|
||
|
||
|
||
VOID ao_queue(UINT lsw, UINT msw);
|
||
VOID ao_queue(ULONG time) ; (conceptual)
|
||
|
||
|
||
Queue a request on the timer for a relative timeout (using active.stat as the completion status word)
|
||
where time is the required time interval to the timer completion in tenths of a second. The uLonc time is
|
||
actually passed in the message as two UINT parameters, 1sw (least significant word) and msw (most
|
||
significant word).
|
||
|
||
|
||
Sets active.isactive tO TRUE.
|
||
|
||
|
||
Only one timer request (either relative or absolute) may be outstanding at any one time since active.stat
|
||
is used for either timer request.
|
||
|
||
|
||
The timer will receive an ao_RUN message on expiry of the timeout.
|
||
|
||
|
||
13-2
|
||
|
||
|
||
13. TIMER ACTIVE OBJECT CLASSES
|
||
|
||
|
||
J TM_QABSOLUTE Queue (absolute)
|
||
|
||
|
||
VOID tm_qabsolute(UINT lsw, UINT msw);
|
||
VOID tm_qabsolute(ULONG time); (conceptual)
|
||
|
||
|
||
Queue a request on the timer for an absolute timeout (using active.stat as the completion status word)
|
||
where time is the absolute system time at which the timer is to complete. The uLonc time is actually
|
||
passed in the message as two uINT parameters, 1sw (least significant word) and msw (most significant
|
||
word).
|
||
|
||
|
||
Sets active.isactive tO TRUE.
|
||
|
||
|
||
Only one timer request (either relative or absolute) may be outstanding at any one time since active.stat
|
||
is used for either timer request.
|
||
|
||
|
||
The timer will receive an ao_RUN message on expiry of the absolute timeout.
|
||
|
||
|
||
ANIMATOR
|
||
|
||
|
||
gq own
|
||
|
||
|
||
priority message
|
||
|
||
|
||
isactive interval
|
||
|
||
|
||
The anrmator class supplies the functionality to send a message to an object at regular intervals, the
|
||
message, object and time interval being specified at initialisation.
|
||
|
||
|
||
Since the intention is that antmator will be used to drive an animation sequence, it runs at a priority
|
||
which is much higher than that normally used by timers but which, at the same time, is less than
|
||
PRIORITY_ACTIVE_WSERV So that window server events - particularly redraw events resulting from the
|
||
animation - are not blocked. The actual priority is set to PRIORITY_ACTIVE_WSERV - 1.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file timer.cl (generated header file timer.g).
|
||
|
||
|
||
CLASS animator timer
|
||
|
||
Sends regular messages eg to drive animation
|
||
{
|
||
REPLACE ao_init
|
||
REPLACE ao_run
|
||
|
||
|
||
TYPES
|
||
{
|
||
typedef struct Must be in property order
|
||
{
|
||
PR_ROOT *own; send messages to this object
|
||
INT message; message number to send
|
||
INT interval; delay between subsequent messages in tenths of a second
|
||
INT first; delay before first message back in tenths of a second
|
||
} IN_ANIMATOR;
|
||
}
|
||
PROPERTY
|
||
{
|
||
PR_ROOT *own; send messages to this object
|
||
INT message; the number of the message to send
|
||
INT interval; interval between messages
|
||
|
||
|
||
}
|
||
|
||
|
||
13 -3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Property
|
||
animator.own the handle of an object to which messages will be sent (this will normally
|
||
be the object which owns the instance of anrmaTorR)
|
||
animator.message the number of the message to be sent to animator.own
|
||
animator.interval the time interval, in tenths of a second, between the sending of two
|
||
|
||
|
||
successive messages
|
||
|
||
|
||
ANIMATOR methods
|
||
|
||
|
||
AO_INIT Initialise
|
||
|
||
|
||
VOID ao_init (IN_ANIMATOR *pin) ;
|
||
Initialise the animator object by:
|
||
¢ supersending an AO_INIT message, which opens a timer channel
|
||
|
||
|
||
e setting active.priority to PRIORITY_ACTIVE_WSERV-1 and sending the application manager an
|
||
AM_ADD_TASK message to add the animator object to the application manager's active object task
|
||
queue.
|
||
|
||
|
||
e setting up animator.own, animator.message and animator.interval from the data pointed to by pin.
|
||
|
||
|
||
e sending itself an AO_QUEUE message with the interval timeout value specified by pin->first. In
|
||
effect, this defines the time interval before the animator object receives the first Ao_RUN message.
|
||
|
||
|
||
AO_RUN Run
|
||
|
||
|
||
INT ao_run(VOID)
|
||
|
||
Handle the completion of the timer request by:
|
||
|
||
e sending the message animator.message to the object animator.own
|
||
|
||
e sending itself an AO_QUEUE message with the timeout value specified by animator.interval
|
||
|
||
|
||
e returning RUN_ACTIVE_USED
|
||
|
||
|
||
BUZSND
|
||
|
||
|
||
ACTIVE TIMER BUZSND
|
||
|
||
|
||
q snd
|
||
priority sndrep
|
||
isactive sndnum
|
||
pcb snddelay
|
||
stat sndvolume
|
||
h_done
|
||
|
||
|
||
m_done
|
||
|
||
|
||
tm_qabsolute ao_init
|
||
|
||
|
||
aorinit ao_cancel
|
||
|
||
|
||
aerqueu ao_queue
|
||
|
||
|
||
ao_run
|
||
|
||
|
||
The suzsno class provides the means for an application to generate alarm sound sequences.
|
||
|
||
|
||
Each alarm sequence consists of one of two possible sounds repeated eight times with a two second
|
||
interval between each sound. The volume of the sound is increased with each repetition.
|
||
|
||
|
||
13-4
|
||
|
||
|
||
13. TIMER ACTIVE OBJECT CLASSES
|
||
|
||
|
||
The sound itself can be either a 'rings' sequence or a 'chimes' sequence and is selected when an ao_INIT
|
||
message is received.
|
||
|
||
|
||
The sounds are generated by means of the sound driver as described in the Sound chapter of the I/O
|
||
Devices Reference manual. Since only one user may have access to the sound system at any one time,
|
||
BUZSND Serialises multiple access requests from different applications. To avoid monopolising the sound
|
||
driver, the channel is opened and closed for each sound in the sequence.
|
||
|
||
|
||
This active object is interesting, in that it may have an outstanding request on either the sound or the
|
||
timer channel, but not both at the same time; the two channels alternately use active.isactive and
|
||
active.stat. The descriptions of the ao_cance1 and the ao_run methods include sample code to clarify
|
||
the explanation of the techniques involved.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file timer.cl (generated header file timer.g).
|
||
|
||
|
||
CLASS buzsnd timer
|
||
Buzzer sound generator
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE ao_init Init timer and add to appman task list
|
||
REPLACE ao_cancel Cancel the timer or sound
|
||
REPLACE ao_queue Start a sound
|
||
REPLACE ao_run Handle next step of sound sequence
|
||
PROPERTY
|
||
{
|
||
UBYTE *snd; Open sound channel handle
|
||
UWORD sndrep; Number of repeats to do
|
||
UWORD sndnum; Which sound number to use
|
||
UWORD snddelay; Delay between repeats
|
||
UWORD sndvolume; For SND: growing volume
|
||
PR_ROOT *h_done; Handle to receive completion message
|
||
UWORD m_done; Method number for above
|
||
}
|
||
}
|
||
Property
|
||
buzsnd.snd the channel handle of the sound driver, while the sound driver is being
|
||
used.
|
||
buzsnd.sndrep the remaining number of repetitions in the current sound sequence
|
||
buzsnd.sndnum which sound to use (0 for a 'rings' sequence or | for a 'chimes' sequence)
|
||
buzsnd.snddelay the time, in tenths of a second, of the delay between successive sounds
|
||
buzsnd.sndvolume the volume of the current sound in the sequence
|
||
buzsnd.h_done NULL, or the handle of the object to which a message is sent on completion
|
||
|
||
|
||
of the sound sequence
|
||
|
||
|
||
buzsnd.m_done the message number to be sent on completion of the sound sequence
|
||
|
||
|
||
BUZSND methods
|
||
AO_INIT Initialise
|
||
|
||
|
||
VOID ao_init (UINT sndnum) ;
|
||
|
||
|
||
Open a timer device channel by supersending an ao_InrIT message to the T1mer superclass, store sndnum
|
||
(either a O for a 'rings' sequence or a | for a 'chimes' sequence ) in buzsnd.sndnum, Set appman.priority
|
||
to PRIORITY_ACTIVE_REPEATER and send the application manager an aM_ADD_TASK message.
|
||
|
||
|
||
Calls p_1eave on error, typically with the error z_GEN_NOMEMoRY.
|
||
|
||
|
||
13-5
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
J AO CANCEL Cancel
|
||
|
||
|
||
VOID ao_cancel (VOID)
|
||
Cancel either the timer or the sound driver, whichever is currently running.
|
||
|
||
|
||
If the sound channel is open (buzsnd.snd is non-zero), any outstanding request is cancelled using the
|
||
PLIB I/O p_rcancet service. The sound channel is closed and buzsnd.snd is set to NULL so that further
|
||
closes are harmless.
|
||
|
||
|
||
In all cases the ao_cance1 method then supersends an ao_caNcEL message to cancel any outstanding timer
|
||
request. As with all ao_cance1 methods, this is harmless if there is no outstanding request.
|
||
|
||
|
||
Finally, buzsnd.sndrep and buzsnd. snddelay are Set to their starting values of 8 and 20 (i.e.
|
||
20 by 1/10th second) respectively, and buzsnd. sndvolume is set to one of two starting values depending on
|
||
whether the user has set the machine to generate loud or quiet sounds.
|
||
|
||
|
||
METHOD VOID buzsnd_ao_cancel (PR_BUZSND *self)
|
||
{
|
||
if (self->buzsnd.snd) /* destroy may call cancel if init fails */
|
||
{
|
||
p_iow2 (self->buzsnd.snd,P_FCANCEL); /* all harmless if not running */
|
||
p_waitstat (&self->active.stat); /* see note ++ */
|
||
self—>active.isactive=FALSE; /* see note ++ */
|
||
p_close(self->buzsnd.sndqd);
|
||
self-—>buzsnd.snd=NULL;
|
||
}
|
||
p_supersend2 (self,O_AO_ CANCEL); /* timer cancel is harmless if not running */
|
||
self—>buzsnd.sndrep=8;
|
||
self->buzsnd.snddelay=20; /* in tenths of a second */
|
||
self—>buzsnd.sndvolume=(p_getsnd() &E_SOUND_LOUD) ?
|
||
(E_SOUND_MIN_VOLUME-1) *2+1: (E_SOUND_MIN_VOLUME) *2+1;
|
||
}
|
||
|
||
|
||
While the calculation for buzsnd.sndvolume in the last line of the code is obscure, it does represent the
|
||
most efficient way (in conjunction with the ao_run method) of calculating a gradually increasing volume.
|
||
|
||
|
||
Note
|
||
|
||
|
||
For the byte-conscious programmer, these two lines (marked ++) are not strictly necessary. These actions
|
||
will be performed within the p_supersend of an ao_canceL which follows a few lines further down. This
|
||
relies on the fact that the timer and sound channels share the same status word and never have
|
||
simultaneous outstanding requests.
|
||
|
||
|
||
J AO_QUEUE Queue
|
||
|
||
|
||
VOID ao_queue(PR_ROOT *handle, UINT method);
|
||
Start the generation of a sound sequence.
|
||
|
||
|
||
Any currently outstanding sound being generated is cancelled by sending itself an ao_caNcEL message,
|
||
which also resets the sound control parameters buzsnd. sndvolume, buzsnd.sndrep and buzsnd. snddelay
|
||
to their starting values. The handie and method values are stored in buzsnd.h_done and buzsnd.m_done
|
||
respectively.
|
||
|
||
|
||
The sound generation sequence is started off by setting active.isactive to TRUE and calling p_iosignal.
|
||
|
||
|
||
The ao_run method will be called by the active object scheduling code in the application manager when
|
||
no other events of higher priority are outstanding.
|
||
|
||
|
||
AO_ RUN Run
|
||
|
||
|
||
INT ao_run (VOID)
|
||
Make alternate requests for a sound or a timeout until the sound sequence is complete.
|
||
If the last to run was the sound driver:
|
||
|
||
e the sound driver is closed and buzsnd. snd is set to NULL
|
||
|
||
|
||
e if the sound sequence is not complete, the timer is queued by supersending an ao_QUEUE message
|
||
with a timeout as defined by buzsnd.snddelay (2 seconds).
|
||
|
||
|
||
13 - 6
|
||
|
||
|
||
13. TIMER ACTIVE OBJECT CLASSES
|
||
|
||
|
||
if the sound sequence is complete and buzsnd.h_done is non-zero, a buzsnd.m_done message is
|
||
sent to buzsnd.h_done.
|
||
|
||
|
||
If the last to run was the timer:
|
||
|
||
|
||
an attempt is made to open the sound driver
|
||
if the sound driver is currently busy, a five second timeout is queued
|
||
|
||
|
||
if the sound driver has been disabled then the sound sequence is deemed to have completed and
|
||
the completion message is sent, as described above
|
||
|
||
|
||
if the sound driver cannot be opened for any other reason (e.g. insufficient memory being
|
||
available) then p_ieave is called.
|
||
|
||
|
||
if the sound driver is opened successfully, the volume is adjusted so that it gradually becomes
|
||
louder and an asynchronous request is made to generate an alarm sound (this branch requires
|
||
active.isactive to be explicitly set to TRUE)
|
||
|
||
|
||
In all cases the method returns RUN_ACTIVE_USED.
|
||
|
||
|
||
METHOD buzsnd_ao_run(PR_BUZSND *self)
|
||
|
||
|
||
{
|
||
|
||
INT ret;
|
||
UWORD delay;
|
||
UBYTE bb[10];
|
||
E_SOUND c;
|
||
|
||
|
||
if (!self->buzsnd.snd)
|
||
{ /* last to run was the timer */
|
||
|
||
|
||
bb[0]='S';bb[1]='N';bb[2]='D';bb[3]=':';bb[4]=0;
|
||
ret=p_open (&self—>buzsnd.snd, &bb[0]);
|
||
if ((ret==E_FILE_LOCKED) || (ret==E_GEN_INUSE) )
|
||
|
||
|
||
{ /* busy - try again later */
|
||
delay=50; /* 5 seconds */
|
||
p_supersend4 (self,O_AO_QUEUE,delay,0); /* last 2 parameters are a LONG */
|
||
}
|
||
else
|
||
{
|
||
if (ret==E_GEN_FAIL) /* sound driver disabled */
|
||
goto sendOwnerDone; /* immediate completion (silent alarm) */
|
||
f_leave (ret);
|
||
p_iow3 (self—>buzsnd.snd, P_FSENSE, &c) ;
|
||
c.volume=(self-—>buzsnd.sndvolume-—) >>1;
|
||
p_iow3 (self—>buzsnd.snd,P_FSET, &c) ;
|
||
p_ioc4 (self—>buzsnd.snd, E_FALARM, &self—>active.stat, &self-—>buzsnd.sndnum) ;
|
||
self—>active.isactive=TRUE;
|
||
|
||
|
||
else
|
||
{ /* last to run was the sound */
|
||
p_close(self->buzsnd.snd);
|
||
self—>buzsnd.snd=0;
|
||
if (--self->buzsnd.sndrep)
|
||
{
|
||
p_supersend4 (self,O_AO_QUEUE, self—>buzsnd.snddelay, 0);
|
||
/* last 2 pars are a LONG */
|
||
}
|
||
else
|
||
{
|
||
if (self->buzsnd.h_done) +
|
||
p_send2 (self-—>buzsnd.h_done, self—>buzsnd.m_done) ;
|
||
|
||
|
||
}
|
||
|
||
|
||
return (RUN_ACTIVE_USED) ;
|
||
}
|
||
|
||
|
||
13-7
|
||
|
||
|
||
CHAPTER 14
|
||
|
||
|
||
FILE ACTIVE OBJECTS
|
||
|
||
|
||
This chapter describes the ractive class (subclassed by all active objects which perform asynchronous
|
||
operations on files) and its FScAN, FNODE, Fcasy and Fcsync subclasses.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e the acTIvE class
|
||
|
||
|
||
e the file server and file system services as described in the Files chapter of the PLIB Reference
|
||
manual
|
||
|
||
|
||
Class diagram
|
||
i
|
||
¢ active /
|
||
Ss )
|
||
|
||
|
||
7
|
||
fe es
|
||
|
||
|
||
¢ factive /
|
||
|
||
|
||
pe aw fo ae ee ae
|
||
|
||
|
||
la fscan / ¢ fnode / la feasy / ‘4 fesyne /
|
||
2. =i) > a fee FS _)
|
||
|
||
|
||
Qo Ke er ee ke ee
|
||
|
||
|
||
FACTIVE
|
||
|
||
|
||
ACTIVE FACTIVE
|
||
|
||
|
||
q owner
|
||
|
||
|
||
priority
|
||
|
||
|
||
isactive
|
||
pcb
|
||
stat
|
||
|
||
|
||
destroy fa_close
|
||
ao_init
|
||
ao_cancel
|
||
ao_abrun
|
||
ao_queue
|
||
|
||
|
||
ao_run
|
||
|
||
|
||
14-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
The ractrve class provides the basic functionality of all active objects that perform operations on files.
|
||
|
||
|
||
Although not formally an abstract class, ractrve must be subclassed to be useful. The subclass will, in
|
||
general, need to supply at least an ao_queue and an ao_run method.
|
||
|
||
|
||
Although the file server does not support a cancel service (see the Files chapter of the PLIB Reference
|
||
manual) ractive supplies an ao_cance1 method which simulates the cancelling of an outstanding
|
||
asynchronous request. This allows the coding of file-related active objects to follow the style of coding for
|
||
other active objects which, for example, routinely send an ao_caNcEL message prior to destruction of the
|
||
instance.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS factive active
|
||
|
||
|
||
File active object superclass
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE ao_init Set priority and am_add_task
|
||
REPLACE ao_cancel Simulate cancel and close file
|
||
REPLACE ao_abrun Cancel and supersend
|
||
ADD fa_close Close and set pcb to NULL
|
||
PROPERTY
|
||
{
|
||
UBYTE *owner; Owning object
|
||
}
|
||
}
|
||
Property
|
||
factive.owner the handle of the owning object, for use by subclasses, for example, to
|
||
|
||
|
||
report the completion of file activity - not used by racTIvE
|
||
|
||
|
||
FACTIVE methods
|
||
& AO_INIT Initialise
|
||
|
||
|
||
VOID ao_init (UBYTE *owner) ;
|
||
Initialise the file active object by:
|
||
e — setting factive.owner to owner, the handle of the owning object
|
||
e setting active.priority to PRIORITY_ACTIVE_FILES
|
||
|
||
|
||
e sending the application manager an AM_ADD_TASK message to add the file active object to the
|
||
application manager's active object task queue
|
||
|
||
|
||
& AO CANCEL Cancel
|
||
|
||
|
||
VOID ao_cancel (VOID);
|
||
|
||
|
||
Cancel any outstanding file server event and close any open file. This is harmless if there is no
|
||
outstanding event.
|
||
|
||
|
||
Note that the cancellation is simulated since the file server does not support a cancel service (see
|
||
Asynchronous file operations in the Files chapter of the PLIB Reference manual). The end effect is,
|
||
however, indistinguishable from a true cancel in that, if a file server event is outstanding, active.stat is
|
||
set to E_FILE_CANCEL and active.isactive iS set tO FALSE.
|
||
|
||
|
||
In addition, this method sends an ra_cLosE message to ensure that any open file is closed.
|
||
|
||
|
||
14-2
|
||
|
||
|
||
14 FILE ACTIVE OBJECTS
|
||
|
||
|
||
AO_ABRUN Handle error
|
||
|
||
|
||
VOID ao_abrun (VOID) ;
|
||
|
||
|
||
Send itself an ao_caNcEL message to cancel any outstanding file activity and close any open file and then
|
||
supersend an Ao_ABRUN message.
|
||
|
||
|
||
This may leave with any error that could arise in the superclass ac_abrun method.
|
||
|
||
|
||
& FA_CLOSE Close any open file
|
||
|
||
|
||
VOID fa_close(VOID);
|
||
Close (with p_close) any open file whose handle is in active.pcb, and set active.pcb tO NULL.
|
||
|
||
|
||
This method does not call p_ieave. It is a requirement that any subclass must not call p_leave.
|
||
|
||
|
||
FSCAN
|
||
|
||
|
||
ACTIVE FACTIVE
|
||
q
|
||
|
||
|
||
owner flags
|
||
priorityt index
|
||
isactive pname
|
||
pcb match
|
||
stat delim
|
||
finfo
|
||
cork
|
||
pcbarr
|
||
|
||
|
||
name
|
||
|
||
|
||
destroy #a—cetese fs_matchname
|
||
|
||
|
||
ao_init fs_fscan
|
||
ao_cancel ao_queue
|
||
ao_abrun ao_run
|
||
|
||
|
||
fa_close
|
||
|
||
|
||
fs_fscan_end
|
||
fs_dirname
|
||
fs_filename
|
||
fs_end_dirlist
|
||
|
||
|
||
FSCAN Is an abstract subclass of ractive which provides the basic mechanisms for scanning a filing
|
||
system by reading the content of one or more directory files. It is designed to be independent of any
|
||
particular filing system and can be used, for example, with either Macintosh or DOS-compatible filing
|
||
systems.
|
||
|
||
|
||
Subclasses of rscan may be used to scan the filing system to select files which match any of a variety of
|
||
criteria. The subclass must supply the action(s) required when a matching directory or file is found.
|
||
|
||
|
||
It may be noted that on completion of the scan, the whole of each relevant directory file will always have
|
||
been read; files are eliminated by the matching process within the rscan code. This allows, for example,
|
||
subclasses of rscan to extract multiple file specifications in one scan of the directory file or to build file
|
||
name extension lists.
|
||
|
||
|
||
14-3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fscan
|
||
Scans the directory structure for files/dirs and creates variable str arrays
|
||
|
||
|
||
{
|
||
|
||
|
||
factive
|
||
|
||
|
||
REPLACE ao_queue
|
||
REPLACE ao_run
|
||
REPLACE fa_close
|
||
ADD fs_matchname
|
||
ADD fs_fscan
|
||
DEFER fs_fscan_end No more files/dirs
|
||
DEFER fs_dirname
|
||
DEFER fs_filename
|
||
DEFER fs_end_dirlist End of that subdir
|
||
|
||
|
||
CONSTANTS
|
||
{
|
||
|
||
|
||
Queue a directory read
|
||
|
||
Process read completion
|
||
|
||
Close all open directory files
|
||
Match a found name
|
||
|
||
Start a directory scan
|
||
|
||
|
||
Next directory name from scan
|
||
Next file name from scan
|
||
|
||
|
||
! Which types of files caller wants
|
||
FS_WRITABLE
|
||
|
||
|
||
FS_HI
|
||
|
||
|
||
DDEN
|
||
|
||
|
||
FS_SYSTEM
|
||
FS_DIRECTORIES
|
||
|
||
|
||
FS_MO
|
||
|
||
|
||
DIFIED
|
||
|
||
|
||
FS_ALL_FILES
|
||
|
||
|
||
FS_FI
|
||
|
||
|
||
LE_TYPE
|
||
|
||
|
||
P_FAWRITE opposite of DOS Read-only attribute
|
||
P_FAHIDDEN as DOS Hidden attribute
|
||
|
||
P_FASYSTEM as DOS System attribute
|
||
|
||
P_FADIR
|
||
|
||
P_FAMOD as DOS Archive attribute
|
||
|
||
P_FAREAD
|
||
|
||
(FS_HIDDEN|FS_SYSTEM)
|
||
|
||
|
||
FS_INCLUDE_SUBDIRECTORIES 0x1000 Want files from subdirectories
|
||
FS_INCLUDE
|
||
|
||
|
||
FS_EN
|
||
|
||
|
||
D_DIRLIST
|
||
|
||
|
||
FS_PARSE_NAME
|
||
FS_MAX_DIRLEVE
|
||
|
||
|
||
}
|
||
|
||
|
||
PROPERTY
|
||
{
|
||
UWORD
|
||
UWORD
|
||
UBYTE
|
||
UBYTE
|
||
UBYTE
|
||
|
||
|
||
}
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
|
||
fscan.
|
||
|
||
|
||
fscan.
|
||
|
||
|
||
fscan.
|
||
|
||
|
||
fscan.
|
||
|
||
|
||
fscan.
|
||
|
||
|
||
fscan.
|
||
|
||
|
||
14-4
|
||
|
||
|
||
flags
|
||
|
||
|
||
index
|
||
|
||
|
||
pname
|
||
|
||
|
||
match
|
||
|
||
|
||
delim
|
||
|
||
|
||
finfo
|
||
|
||
|
||
flags;
|
||
index;
|
||
*pname;
|
||
*match;
|
||
delim[2]
|
||
|
||
|
||
P_INFO finfo;
|
||
P_FPARSE crk;
|
||
UBYTE *pcbarr[FS_MAX_DIRLEVELS] ;
|
||
UBYTE name[P_FNAMESIZE];
|
||
|
||
|
||
0x2000 Called dirname because of include
|
||
|
||
0x4000 Called end dir list
|
||
|
||
0x8000 Set if generated name to be parsed
|
||
LS 32 Max number of sub dir levels
|
||
|
||
|
||
Controlling flags
|
||
Subdir array index
|
||
Pointer into name[] for read
|
||
Pointer to file name match
|
||
,
|
||
File Info
|
||
Parsed file info
|
||
|
||
|
||
controlling flags, some of which should be set up by the owner before
|
||
sending an Fs_FSCAN message
|
||
|
||
|
||
the index of the first free entry in the fscan.pcbarr array. It should not be
|
||
accessed by any subclass.
|
||
|
||
|
||
a pointer to the file name and extension within the full file specification in
|
||
the fscan.name buffer. Owners and subclasses should treat this as a read-
|
||
only field.
|
||
|
||
|
||
a pointer to a string used to match file names during a scan. It may be set
|
||
up by an owner before sending an rs_Fscan message.
|
||
|
||
|
||
temporary storage for the directory delimiter character (assumed to be a
|
||
single character). It should not be accessed by any subclass.
|
||
|
||
|
||
the PLIB p_inro data for the current file, that is, the file whose name has
|
||
last been read from a directory file. This information may be read, but
|
||
should not be modified, by an owner.
|
||
|
||
|
||
14 FILE ACTIVE OBJECTS
|
||
|
||
|
||
fscan.crk provided the rs_parsE_NawE flag is set in fscan. flags, this contains the
|
||
PLIB p_rparse data for the current file, whose full file specification is in
|
||
the fscan.name buffer. This information may be read by an owner.
|
||
|
||
|
||
fscan.pcbarr an array of up to Fs_MAX_DIRLEVELS handles of open directory files. This
|
||
should not be accessed by a subclass.
|
||
|
||
|
||
fscan.name the full file specification of the current file. An owner may read this name
|
||
directly or may read only the file name via fscan.pname.
|
||
|
||
|
||
FSCAN methods
|
||
AO_QUEUE Directory read
|
||
|
||
|
||
VOID ao_queue (VOID) ;
|
||
Queue a read on the current directory file, setting active.isactive tO TRUE.
|
||
The action may be modified by the ao_run method resulting from a previous read:
|
||
|
||
|
||
e If the previous read produced the name of a directory file and the scan is to extend into nested
|
||
subdirectories (fscan. flags includes rs_INCLUDE_SUBDIRECTORIES) the current value of
|
||
active.pcb Is stored in the fscan.pcbarr array and the new subdirectory is opened before the
|
||
read request is made. A maximum of 32 levels of subdirectory may be open at any one time.
|
||
|
||
|
||
e If the previous read detected that there were no more files in the current directory and directories
|
||
have been nested, then the most recently nested subdirectory handle is restored into active.pcb
|
||
from the fscan.pcbarr array before the read request is made.
|
||
|
||
|
||
Any error causes p_leave to be called.
|
||
|
||
|
||
AO_RUN Process read completion
|
||
INT ao_run(VOID);
|
||
Process the completion of the read of a file name from a directory file and return RUN_ACTIVE_USED.
|
||
|
||
|
||
If the read completed with an £_rF1LE_zoF error, indicating that there are no further entries in the current
|
||
directory file:-
|
||
|
||
|
||
e the file is closed and active.pcb is Set to NULL.
|
||
|
||
|
||
e The delimiter character is picked up (the last character before the filename) and placed in
|
||
|
||
|
||
fscan.delim.
|
||
If directories are nested:-
|
||
@ an FS_END_DIRLIST message is sent to indicate the end of a directory, but not the end of the scan.
|
||
e the run method completes and returns RUN_ACTIVE_USED
|
||
If directories are not nested:-
|
||
@ an FS_FSCAN_END message is sent to indicate the end of the scan.
|
||
e the run method completes and returns RUN_ACTIVE_USED
|
||
If the read completed successfully:-
|
||
|
||
|
||
e if the file name is a volume name, the name is discarded and a new name is requested by calling
|
||
the FScAN ao_queue method directly.
|
||
|
||
|
||
e if none of the flags rs_WRITABLE, FS_HIDDEN, FS_SYSTEM, FS_MODIFIED, FS_ALL_FILES Is Set, the
|
||
name is discarded and a new name is requested by calling the rscan ao_queue method directly.
|
||
|
||
|
||
e if the file is a (DOS) . or .. directory file, the name is discarded and a new name is requested by
|
||
calling the rscan ao_queue method directly.
|
||
|
||
|
||
14-5
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
e if the file is a directory file and either of the rs_DIRECTORIES OF FS_INCLUDE_SUBDIRECTORIES
|
||
flags is set (meaning that there is interest in the directory file name itself or in subdirecrtories)
|
||
then an Fs_DIRNAME message Is sent. If neither flag rs_DIRECTORIES or
|
||
FS_INCLUDE_SUBDIRECTORIES Is set, the name is discarded and a new name is requested by
|
||
calling the rscaNn ao_queue method directly
|
||
|
||
|
||
if the file is not a directory file:-
|
||
|
||
|
||
e flag is set, then the file name in fscan.name is parsed (using p_fparse) with the parsed file name
|
||
information written to fscan.crk.
|
||
|
||
|
||
e an FS_MATCHNAME message is sent. If this returns FaLsz, indicating that the file name does not
|
||
match the specified attributes and (wildcard) name, the name is discarded and a new name is
|
||
requested by calling the rscan ao_queue method directly. If the rs_maTcHNamE message returns
|
||
TRUE then the read of a valid, matching, file name is indicated by sending an rs_FILENAME
|
||
message.
|
||
|
||
|
||
e the run method completes and returns RUN_ACTIVE_USED.
|
||
|
||
|
||
All errors, other than the z_F1LE_zor error discussed above, result in p_leave being called.
|
||
|
||
|
||
& FA_CLOSE Close directory files
|
||
|
||
|
||
VOID fa_close (VOID) ;
|
||
|
||
|
||
Supersend an ra_cLosgE message and close all open directory files.
|
||
|
||
|
||
& FS_MATCHNAME Match a found name
|
||
|
||
|
||
INT fs_matchname (VOID) ;
|
||
|
||
|
||
Check that the file matches the specified combination of rs_MoDIFIED, FS_HIDDEN and Fs_systTen flags. If
|
||
these tests succeed the file name (pointed to by fscan.pname) 1s tested for a match with the (wildcard)
|
||
name pointed to by fscan.match.
|
||
|
||
|
||
Note that the name match is case-sensitive. Since rscan is designed to work independently of any
|
||
particular filing system, matching uses a true wildcard string match (as opposed to a DOS-specific file
|
||
system wildcard match) to select files. Thus the wildcard string "*" will select all files (including those
|
||
with an extension, unlike DOS). This also means that more than one part of a file name can be wildcarded
|
||
with the '*' character, to find, for example, files matching "*fred.*".
|
||
|
||
|
||
Returns true if there is a match, otherwise raLsE.
|
||
This method is called from within the ao_run method.
|
||
|
||
|
||
A subclass may replace this method to provide an alternative name matching algorithm.
|
||
|
||
|
||
FS FSCAN Start a directory scan
|
||
|
||
|
||
VOID fs_fscan(UBYTE *path);
|
||
Start the scan of the file system for directories and files.
|
||
|
||
|
||
The file specification pointed to by path is parsed to extract the directory in which the scan is to start.
|
||
Provided this initial path name does not need to be preserved, path may point to a file specification in
|
||
fscan.name (this field is overwritten during the scan).
|
||
|
||
|
||
If the specified directory is opened successfully, an ao_quEUE message is sent to start the scan.
|
||
Any error causes p_leave to be called.
|
||
|
||
|
||
It is assumed that fscan.match and fscan. flags have previously been set up either by a subclass or by
|
||
the owner as is done, for example, by many of the methods (such as fman_rename) of the rman class,
|
||
described in the File Management Classes chapter.
|
||
|
||
|
||
The fscan.match field should be set to point to a suitable wildcard string.
|
||
|
||
|
||
14-6
|
||
|
||
|
||
14 FILE ACTIVE OBJECTS
|
||
|
||
|
||
The fscan. flags field should contain a bitwise combination of one or more of the following values:
|
||
|
||
|
||
FS_ALL_FILES include all non-directory files that are neither hidden nor system files
|
||
FS_WRITABLE aS FS_ALL_FILES, but excludes write-protected files (see below)
|
||
FS_HIDDEN include hidden files
|
||
|
||
FS_SYSTEM include system files
|
||
|
||
FS_DIRECTORIES include directory files
|
||
|
||
FS_MODIFIED exclude unmodified files (include only files that have p_ramop set)
|
||
FS_INCLUDE_SUBDIRECTORIES extend the scan to subdirectories
|
||
|
||
FS_PARSE_NAME parse file names before reporting them
|
||
|
||
|
||
The supplied £s_matchname method does not test the rs_wR1ITABLE flag which therefore has the same
|
||
effect as the rs_att_Fiues flag. A subclass fs_matchname method may implement this flag as follows:
|
||
|
||
|
||
if ((self->fscan.flags&FS_WRITABLE) && !(self->fscan.finfo.status&P_FAWRITE) )
|
||
return (FALSE) ;
|
||
return (p_supersend2 (self,O_FS_MATCHNAME) ) ;
|
||
|
||
|
||
Deferred FSCAN methods
|
||
|
||
|
||
FS FSCAN_END Scan completion
|
||
|
||
|
||
VOID fs_fscan_end(VOID);
|
||
|
||
|
||
A deferred method indicating the end of the scan and that there are no more files or subdirectories to scan
|
||
into or report back.
|
||
|
||
|
||
This message is sent from within the ao_run method. By the time it is sent, all levels of directory files will
|
||
have been closed.
|
||
|
||
|
||
FS DIRNAME Next directory name
|
||
|
||
|
||
VOID fs_dirname (VOID) ;
|
||
A deferred method indicating that a directory file matching the initial specification has been found.
|
||
|
||
|
||
This message is sent from within the ao_run method, provided that fscan. flags includes either
|
||
FS_DIRNAME Of FS_INCLUDE_SUBDIRECTORIES.
|
||
|
||
|
||
On receipt of this message fscan.finfo contains the file information for the directory file, fscan.name
|
||
contains its full file specification and the fscan.pname points to the directory file name within the full file
|
||
specification. These fields should be regarded as read only.
|
||
|
||
|
||
In order to obtain further files or directories, this method must restart the scan by sending an ao_QUEUE
|
||
message.
|
||
|
||
|
||
FS_FILENAME Next file name
|
||
|
||
|
||
VOID fs_filename (VOID) ;
|
||
|
||
|
||
A deferred method indicating that a file name matching the initial specification has been found. This
|
||
message is sent from within the ao_run method.
|
||
|
||
|
||
On receipt of this message fscan.finfo contains the file information for the file, fscan.name contains its
|
||
full file specification and the fscan.pname points to the file name within the full file specification. If
|
||
fscan.flags includes rs_PARSE_NaME, then fscan.crk contains the parsed file name information. These
|
||
fields should be regarded as read only.
|
||
|
||
|
||
In order to obtain further files or directories, this method must restart the scan by sending an ao_QUEUE
|
||
message.
|
||
|
||
|
||
14-7
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
FS _END_DIRLIST End of subdirectory
|
||
|
||
|
||
VOID fs_end_dirlist (VOID);
|
||
|
||
|
||
A deferred method indicating that the end of a subdirectory has been reached. This message is sent from
|
||
within the ao_run method provided that fscan. flags includes rs_INCLUDE_SUBDIRECTORIES. It is only
|
||
reported at the end of a nested subdirectory and not when the end of the directory in which the scan
|
||
started is reached. The directory file will be closed before this message is sent.
|
||
|
||
|
||
On receipt of this message fscan.name contains the full file specification of the directory file and the
|
||
fscan.pname points to the file name within the full file specification. The information in fscan.finfo and
|
||
fscan.crk is not valid.
|
||
|
||
|
||
In order to obtain further files or directories the scan must be restarted by sending an aco_quEuUE message at
|
||
some point.
|
||
|
||
|
||
FNODE
|
||
|
||
|
||
ACTIVE FACTIVE
|
||
q
|
||
|
||
|
||
owner flags
|
||
priority pname
|
||
isactive oldname
|
||
pcb pcb
|
||
stat
|
||
|
||
|
||
destroy #a—cteose fn_list
|
||
|
||
|
||
ao_init ao_queue
|
||
ao_cancel ao_run
|
||
|
||
|
||
ao_abrun fa_close
|
||
|
||
|
||
fn_end_list
|
||
|
||
|
||
fn_nodename
|
||
|
||
|
||
In EPOC there are multiple filing systems, three of which are ROM::, LOC:: and REM::. The rnopE
|
||
abstract class provides the basic mechanisms to generate filing system node and device lists.
|
||
|
||
|
||
The rnope methods read an item in the filing system (node) list and, if that node supports multiple devices
|
||
(drives) read the device list to generate a node: :device.:\ name. Filing systems (such as ROM-::) that do not
|
||
support multiple devices are ignored.
|
||
|
||
|
||
It is possible to restrict the list to the LOC:: filing system.
|
||
|
||
|
||
Since filing systems are dynamic under EPOC, the names generated may vary between invocations.
|
||
|
||
|
||
14-8
|
||
|
||
|
||
14 FILE ACTIVE OBJECTS
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fnode factive
|
||
Node/Device name list generator
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE ao_queue Read from appropriate channel
|
||
REPLACE ao_run Process read completion
|
||
REPLACE fa_close Closes both open channels
|
||
ADD fn_list Start to generate a list
|
||
DEFER fn_end_list Handle list generate completion
|
||
DEFER fn_nodename Process an item in the list
|
||
CONSTANTS
|
||
{
|
||
FNODE_NODE_ARRAY 0x01 Reading node list
|
||
FNODE_DEVICE_ARRAY 0x02 Reading device list
|
||
FNODE_LOCAL_ONLY 0x04 Read local node list only
|
||
}
|
||
PROPERTY
|
||
{
|
||
UWORD flags; Controlling flags
|
||
UBYTE *pname; Where to read into
|
||
UBYTE *oldname; Node read ptr
|
||
UBYTE *pcb; Node pcb while reading device list
|
||
}
|
||
}
|
||
Property
|
||
fnode.flags internal controlling flags
|
||
fnode.pname the offset into the data buffer of where to write the node or device name. It
|
||
|
||
|
||
should not be accessed by an owning object.
|
||
|
||
|
||
fnode.oldname the offset into the data buffer of where to read the next node name. It
|
||
should not be accessed by an owning object.
|
||
|
||
|
||
fnode.pcb while reading a device list, the handle of the opened node list file is saved
|
||
here. It should not be accessed by an owning object.
|
||
|
||
|
||
FNODE methods
|
||
& AO_QUEUE Read from appropriate channel
|
||
|
||
|
||
VOID ao_queue (VOID) ;
|
||
|
||
|
||
Queue a read on either the node list or device list, depending on which is appropriate at the time and set
|
||
|
||
|
||
active.isactive tO TRUE.
|
||
|
||
|
||
Note that node information as would be written to a p_NInFo structure is not requested in the read.
|
||
|
||
|
||
AO_RUN Process read completion
|
||
|
||
|
||
INT ao_run(VOID);
|
||
|
||
|
||
Process the completion of a read that was initiated by the ao_queue method and return RUN_ACTIVE_USED.
|
||
The read may have been from either the node list or a device list. The two cases are discussed under their
|
||
respective headings.
|
||
|
||
|
||
Node List Read
|
||
|
||
|
||
The completion status is tested for an E_FILE_£oF error, indicating that no further nodes exist; if this is
|
||
the case, the scan is terminated by closing the node list and sending an rN_END_LIsT message. Otherwise,
|
||
the node is checked for validity:-
|
||
|
||
|
||
e the node must support multiple devices
|
||
|
||
|
||
e if the FNopE_LocaL_onty flag is present, only the LOC:: node is valid.
|
||
|
||
|
||
14-9
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
For a valid node, the device list for that node is opened and an ao_QuzuUE message sent to read an item
|
||
from the device list, otherwise an ao_QuEUE message is sent to read a further item from the node list.
|
||
|
||
|
||
Device List Read
|
||
|
||
|
||
The completion status is tested for an =_FILE_EoF error, indicating that no further devices exist on the
|
||
current node. If the completion status is E_FILE_EOF:-
|
||
|
||
|
||
e the device list is closed
|
||
@ an AO_QUEUE message is sent to read the next item from the node list.
|
||
If the read completed successfully, an rN_NODENAME message is sent.
|
||
|
||
|
||
The owner is responsible for re-queuing a read on the node/device list by sending an ao_quEUE message at
|
||
some future point after sending the rn_NODENAME message.
|
||
|
||
|
||
For all errors other than the z_riLe_zor errors discussed above, p_leave is called.
|
||
|
||
|
||
& FA_CLOSE Close both open channels
|
||
|
||
|
||
VOID fa_close (VOID) ;
|
||
|
||
|
||
Close any open node and device lists setting both the open handles to nun. The node list is closed by
|
||
supersending an ra_cLosE message; the device list is closed by calling p_close.
|
||
|
||
|
||
FN_LIST Start list generation
|
||
|
||
|
||
VOID fn_list (UBYTE *pname, UINT flags);
|
||
|
||
|
||
Start the scan to generate node: :device:\ names by opening the node list and sending an ao_QuEUE
|
||
message.
|
||
|
||
|
||
The user-supplied buffer at pname is assumed to be at least p_rNames1zeE bytes in length. It is used as the
|
||
output buffer for each generated name and hence, must be preserved until an FN_END_LIST message is
|
||
received. The user may access this buffer only when no read is outstanding, for example, during the
|
||
processing of the deferred rN_NODENAME message.
|
||
|
||
|
||
The value of f1ags may be either rNopE_LocAL_oNLy to read only the LOC:: filing system, or nuu1 to read
|
||
all filing system device lists.
|
||
|
||
|
||
Deferred FNODE methods
|
||
FN_END LIST Handle completed list
|
||
|
||
|
||
VOID fn_end_list (VOID) ;
|
||
|
||
|
||
A deferred method indicating that the scan is complete and that all node: :device:\ names have been
|
||
generated.
|
||
|
||
|
||
On receipt of this message the node and device lists will have been closed. The user-supplied buffer (see
|
||
the fn_1ist method) may now be discarded.
|
||
|
||
|
||
FN _NODENAME Process a list item
|
||
|
||
|
||
VOID fn_nodename (VOID) ;
|
||
|
||
|
||
A deferred method indicating that a node: :device:\ name has been generated. The name may be read from
|
||
the user-supplied buffer (see the fn_1ist method).
|
||
|
||
|
||
The user is responsible for restarting the scan for the next name by sending an ao_QuEUE message.
|
||
|
||
|
||
14-10
|
||
|
||
|
||
14 FILE ACTIVE OBJECTS
|
||
|
||
|
||
FCASY
|
||
|
||
|
||
ACTIVE FACTIVE
|
||
q
|
||
|
||
|
||
owner recvname
|
||
priority flags
|
||
isactive
|
||
|
||
pcb
|
||
|
||
stat
|
||
|
||
|
||
destroy ao_cancel
|
||
|
||
|
||
ao_init ao_run
|
||
|
||
aereancet ao_queue
|
||
|
||
ao_abrun fa_close
|
||
fc_write
|
||
|
||
|
||
fc_open
|
||
|
||
|
||
fc_request_comp
|
||
|
||
|
||
The rcasy abstract class subclasses ractIve to provide a set of methods to perform a segmented read or
|
||
|
||
write of a single file. In other words, it allows a file to be read or written to in a finite number of discrete
|
||
portions. This permits a large file to be processed (which would otherwise be impossible due to memory
|
||
|
||
constraints)
|
||
|
||
|
||
Fcasy does not support a combination of reading and writing to the same file.
|
||
|
||
|
||
Typical uses are in copying a file or in XMODEM file transfer, where the source and target files are each
|
||
represented by a separate instance of a subclass of rcasy.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fcasy factive
|
||
File copy/save/load asynchronous routines
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE ao_cancel Abandon and clean up correctly
|
||
|
||
REPLACE ao_run Maybe cleanup and send itself fc_request_comp
|
||
REPLACE ao_queue Async file read
|
||
|
||
REPLACE fa_close Close file, set recname to NULL
|
||
|
||
ADD fc_write Async file write
|
||
|
||
ADD fc_open Open/create file for load/save
|
||
|
||
DEFER fc_request_comp That async request has completed
|
||
|
||
CONSTANTS
|
||
|
||
|
||
{
|
||
|
||
! Display info flags
|
||
FCOPY_DISP_SFTYPE 0x01
|
||
FCOPY_DISP_SFSIZE 0x02
|
||
FCOPY_DISP_SFDATE 0x04
|
||
FCOPY_DISP_SFNAME 0x08
|
||
FCOPY_DISP_RFTYPE 0x10
|
||
FCOPY_DISP_RFSIZE 0x20
|
||
FCOPY_DISP_RFDATE 0x40
|
||
FCOPY_DISP_RFNAME 0x80
|
||
FCOPY_DISP_BLKSIZ 0x100
|
||
FCOPY_DISP_BLKNO 0x200
|
||
FCOPY_DISP_PROTOCOL 0x400
|
||
|
||
! Controlling Flags
|
||
FCASY_READ_QUEUED 0x01
|
||
FCASY_WRITE_QUEUED 0x02
|
||
}
|
||
|
||
|
||
14-11
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TYPES
|
||
|
||
|
||
{
|
||
typedef struct
|
||
|
||
|
||
{
|
||
|
||
|
||
UWORD flags; FCOPY_DISP_... flags indicate which fields are
|
||
valid
|
||
UWORD protocol; Which protocol being used
|
||
UWORD blksiz; Size of each block
|
||
UWORD blkno; Current block number
|
||
UWORD sftype; Source file type
|
||
UWORD rftype; Receive file type
|
||
ULONG sfsize; Source file size
|
||
ULONG rfsize; Receive file size
|
||
ULONG sfdate; Source file last modification date
|
||
ULONG rfdate; Receive file last modification date
|
||
UBYTE *sfname; Source file name (source for reads)
|
||
UBYTE *rfname; Receive file name (destination for writes)
|
||
} FCOPY_DISP;
|
||
}
|
||
PROPERTY
|
||
{
|
||
UBYTE *recvname; Receive file name
|
||
UWORD flags; Controlling flags
|
||
}
|
||
}
|
||
Property
|
||
fcasy.recvname a pointer to the name of the file being written to (nut if the file is being
|
||
read)
|
||
fcasy.flags internal controlling flags; while a request is outstanding, contains a value
|
||
|
||
|
||
indicating the nature of the request (either rcasy_READ_QUEUED or
|
||
FCASY_WRITE_QUEUED)
|
||
|
||
|
||
FCASY methods
|
||
& AO_CANCEL Cancel request
|
||
|
||
|
||
VOID ao_cancel (VOID);
|
||
Cancel any outstanding read or write by supersending an ao_cANCEL message.
|
||
|
||
|
||
If the instance represents a file that is opened for writing, the file is then explicitly deleted.
|
||
|
||
|
||
& AO_QUEUE Read request
|
||
|
||
|
||
VOID ao_queue(UBYTE *buf, UWORD *plen);
|
||
Queue a read of *pien bytes into buf from the file whose channel handle is in active.pcb.
|
||
|
||
|
||
Sets active.isactive to TRUE and sets the rcAsy_READ_QUEUED flag in fcasy. flags to indicate a read
|
||
request.
|
||
|
||
|
||
Since the read is asynchronous, the memory pointed to by buf and plen must be preserved until the
|
||
request completes.
|
||
|
||
|
||
& FC_WRITE Write request
|
||
|
||
|
||
VOID fc_write(UBYTE *buf, UWORD *plen);
|
||
Queue a write of *pien bytes from bug to the file whose channel handle is in active.pcb.
|
||
|
||
|
||
Sets active.isactive to TRUE and sets the FcAsy_WRITE_QUEUED flag in fcasy. flags to indicate a write
|
||
request.
|
||
|
||
|
||
Since the write is asynchronous, the memory pointed to by buf and pien must be preserved until the
|
||
request completes.
|
||
|
||
|
||
14-12
|
||
|
||
|
||
14 FILE ACTIVE OBJECTS
|
||
|
||
|
||
AO_RUN Process read or write completion
|
||
|
||
|
||
INT ao_run(VOID);
|
||
Process the completion of either a read or a write request.
|
||
|
||
|
||
Note that the object is expected to handle the completion of either a read request (Aao_QUEUE) or a write
|
||
request (FC_WRITE) but not a mixture of the two.
|
||
|
||
|
||
Clears the FcASY_READ_QUEUED and FCASY_WRITE_QUEUED bits in fcasy. flags.
|
||
|
||
|
||
If active.stat 1S TRUE (indicating an error), it sends itself an ao_cancEeL message. This closes the file on
|
||
detection of a read or write error (read errors include z_F1LE_EOoF); in the case of a write it ensures that the
|
||
partially written file is deleted.
|
||
|
||
|
||
Sends itself an rc_REQUEST_comp message before returning RUN_ACTIVE_USED.
|
||
|
||
|
||
& FA_CLOSE Close the file
|
||
|
||
|
||
VOID fa_close (VOID) ;
|
||
|
||
|
||
Close the file by supersending an ra_cLosE message. Sets fcasy.recvname (which is used on detection of
|
||
an error to delete any partially written file) to nuLL.
|
||
|
||
|
||
& FC_OPEN Open a file
|
||
|
||
|
||
INT fc_open(TEXT *name, INT mode, FCOPY_DISP *pdinfo) ;
|
||
|
||
|
||
Open the file with name in the buffer pointed to by name (which must be at least p_rwames1ze bytes long)
|
||
in the specified mode and fill in the struct at pdinfo with as much information as possible about the file.
|
||
The items that have been written to *pdinfo are indicated by the corresponding flag bits being set in
|
||
pdinfo->flags.
|
||
|
||
|
||
It is assumed that the file is to be opened for either reading or writing, but not both. The value of mode
|
||
must include one of p_roPEN, P_FCREATE Of P_FREPLACE (otherwise the method returns &_GEN_aRG).
|
||
|
||
|
||
Sets pdinfo->sfname tO name and then parses name (using p_fparse) to ensure that the file name is valid.
|
||
If the file is opened for writing and the specified directory does not exist, it is created automatically.
|
||
|
||
|
||
If the file is to be opened for reading (mode includes p_ropen), the file size and last modification date are
|
||
written to pdinfo->sfsize and pdinfo->sfdate respectively. Depending on whether the file type is
|
||
binary or text, pdinfo->sftype 1s set to P_FSTREAM Or P_FTEXT. The value of mode is augmented by oring
|
||
in p_rsuare. If the file type is text, mode is converted to use P_FSTREAM_TEXT (rather than p_FTExT) to
|
||
optimise the reading of the file.
|
||
|
||
|
||
If the file is to be opened for writing the method will return an error if mode includes p_rcreatE and the
|
||
file exists or if mode includes p_FREPLACE and name specifies a directory file. Otherwise pdinfo->rfname iS
|
||
set to name and the value of mode is augmented by oring in p_ruppate. If the file is opened successfully
|
||
fcasy.recvname 1S set to name. The data space pointed to by name must therefore be preserved until the file
|
||
has been closed.
|
||
|
||
|
||
Returns zero if successful, otherwise a negative error number.
|
||
|
||
|
||
14 - 13
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Deferred FCASY methods
|
||
|
||
|
||
FC_REQUEST COMP Inform of completion
|
||
|
||
|
||
VOID fc_request_comp (VOID);
|
||
|
||
|
||
A deferred method, called from within the ao_run method, indicating that the read or write request has
|
||
completed.
|
||
|
||
|
||
If there was a read or write error, the file will already have been closed and, if appropriate, deleted by
|
||
means of an ao_cANcEL message. The subclass is, however, responsible for checking the completion status
|
||
(active.stat) and performing any additional error handling.
|
||
|
||
|
||
In the absence of such errors, the user is responsible for continuing the operation by sending the next
|
||
AO_QUEUE Of FC_WRITE message.
|
||
|
||
|
||
Errors in this method should result in p_leave being called.
|
||
|
||
|
||
FCSYNC
|
||
|
||
|
||
ACTIVE FACTIVE FCASY FCSYNC
|
||
q
|
||
|
||
|
||
recvname
|
||
|
||
|
||
priority flags
|
||
|
||
|
||
isactive
|
||
pcb
|
||
stat
|
||
|
||
|
||
destroy ao_cancel ao_queue
|
||
|
||
|
||
ao_init ao_run fc_write
|
||
|
||
|
||
2 Soe
|
||
ao_abrun fa_close
|
||
fe-write
|
||
|
||
|
||
fc_open
|
||
|
||
|
||
fc_request_comp
|
||
|
||
|
||
The rcsync abstract class subclasses rcasy. It converts rcasy to use synchronous file read and write
|
||
services, otherwise it is identical to Fcasy.
|
||
|
||
|
||
As with Fcasy, it is assumed that an instance of a subclass of rcsync is used to either read from or write to
|
||
a file.
|
||
|
||
|
||
Since file access is synchronous, it should only be used in situations where the read and write operations
|
||
are guaranteed to complete quickly. Thus, it is effectively restricted to use with files on the local filing
|
||
system.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fcesync fcasy
|
||
Synchronous file I/O for local file system
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE ao_queue Synchronous file read
|
||
REPLACE fc_write Synchronous file write
|
||
}
|
||
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
14-14
|
||
|
||
|
||
14 FILE ACTIVE OBJECTS
|
||
|
||
|
||
FCSYNC methods
|
||
& AO_QUEUE Read request
|
||
|
||
|
||
INT ao_queue(UBYTE *buf, UWORD *plen);
|
||
|
||
|
||
Perform a synchronous read of *pien bytes into but from the file whose channel handle is in active.pcb
|
||
by supersending the ao_quEvE message and then waiting (with p_waitstat) ON active.stat for the read
|
||
to complete.
|
||
|
||
|
||
Sends itself an ao_cancet (which closes the file and sets active.stat to E_FILE_CANCEL) if the read
|
||
completes with an error. In particular, since =_FILE_EoF is not distinguished from other errors, the file
|
||
will be closed automatically on reading to the end of the file.
|
||
|
||
|
||
On exit active.isactive and fcasy.flags are both guaranteed to be zero.
|
||
|
||
|
||
Returns the value of active.stat.
|
||
|
||
|
||
& FC_WRITE Write request
|
||
|
||
|
||
INT fc_write(UBYTE *buf, UINT len);
|
||
|
||
|
||
Perform a synchronous write of 1en bytes from bur to the file whose channel handle is in active.pcb by
|
||
supersending the rc_wRITE message and then waiting (with p_waitstat) ON active.stat for the write to
|
||
complete.
|
||
|
||
|
||
Sends itself an ao_cance. (which closes and deletes the file, and sets active.stat to E_FILE_CANCEL) if the
|
||
write completes with an error.
|
||
|
||
|
||
On exit active.isactive and fcasy.flags are both guaranteed to be zero.
|
||
|
||
|
||
Returns the value of active.stat.
|
||
|
||
|
||
14-15
|
||
|
||
|
||
CHAPTER 15
|
||
|
||
|
||
FILE Lists
|
||
|
||
|
||
The classes described in this chapter are concerned with the navigation of the directories of a filing system
|
||
and with the generation and storage of directory and file name lists.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e active objects and the rnopE and Fscawn abstract classes
|
||
e the vastR and vaxvar variable array classes
|
||
e the file server node, device, directory and file services
|
||
e the p_enter and p_leave error handling services
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
ra ros sitet de fi ae ti ws
|
||
¢ Varoot / ¢ active /
|
||
ly ) mS
|
||
x f e f _
|
||
Pore ee ‘
|
||
¢ Vafix / ¢ factive /
|
||
~“ )
|
||
a _ )
|
||
|
||
|
||
min — are a ‘Se
|
||
|
||
|
||
f Rey oe? Peay
|
||
¢ Vaflat / , vastr / ¢ sh j Va “ {node ?
|
||
|
||
|
||
es ue N i
|
||
|
||
|
||
pres
|
||
a vaxvar
|
||
|
||
|
||
oe
|
||
a ee Pale,
|
||
|
||
|
||
y pselvar / ¢ Pnode /
|
||
ee ee
|
||
ae San
|
||
|
||
|
||
15-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
PSELVAR
|
||
|
||
|
||
nrec ke rlen gran
|
||
nspc
|
||
|
||
|
||
destroy arepta i atest
|
||
va_count va_compress | va_copy
|
||
va_delete a—detetem va_reclen
|
||
va_sort Farinsertm va_replace
|
||
|
||
|
||
va_key va_capacity | va_init
|
||
|
||
|
||
va_findisgq Lad va_prec va_deletem
|
||
va_insertisq oe ES va_insertm
|
||
va_append b va_pbuf
|
||
va_insert
|
||
|
||
va_search
|
||
|
||
va_compare
|
||
|
||
va_reset
|
||
|
||
Wartest
|
||
|
||
|
||
The psetvar class subclasses the vaxvar variable array class. It is intended to be used to store an ordered
|
||
array of file and directory names and the additional method is tailored to the special sorting schemes
|
||
needed.
|
||
|
||
|
||
This class is defined specifically for use by the pset class, described later. The va_test method assumes
|
||
that varoot .key.desc specifies ascending or descending order as normal for the variable array classes,
|
||
but that varoot.key.fold contains one of the psEL_ORDER_xxx values defined below. The
|
||
|
||
varoot .key.ofs and varoot .key.1len fields are not used.
|
||
|
||
|
||
The psEL ps_order method writes directly to the varoot .key.desc and varoot .key. fold fields of its
|
||
component instance of psELvar (as an alternative to providing psELvaR with a subclassed va_key method).
|
||
|
||
|
||
Each psE.var record is assumed to be an Rc_vaxvar struct, whose buf field points to an allocated heap
|
||
cell containing a psEL_REc struct. The contents of this struct are determined by the owning ese. The
|
||
name field contains either a file name or a directory name. Note that the namien field contains meaningful
|
||
data only if the names are ordered by extension.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS pselvar vaxvar
|
||
Holds the files/dir names in order - dir names first then file names
|
||
{
|
||
REPLACE va_test
|
||
CONSTANTS
|
||
{
|
||
PSEL_FLAG_TAG Oxl
|
||
|
||
|
||
PSEL_ORDER_NAME 0 Order by name alphabetically (default)
|
||
PSEL_ORDER_TIME al Order by time of creation
|
||
PSEL_ORDER_DATE 2 Order by date of creation
|
||
PSEL_ORDER_SIZE 3 Order by size of file
|
||
PSEL_ORDER_EXT 4 Order by extension
|
||
}
|
||
TYPES
|
||
{
|
||
typedef struct
|
||
{
|
||
UWORD flags; Tagging flags info
|
||
UWORD namlen; Offset in name of extension
|
||
P_INFO info; File info
|
||
|
||
|
||
UBYTE name[P_FNAMESIZE]; Max file name size buffer
|
||
} PSEL_REC;
|
||
|
||
|
||
}
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
15 -2
|
||
|
||
|
||
15 FILE LISTS
|
||
|
||
|
||
PSELVAR methods
|
||
& VA_TEST Compare two records by pointer
|
||
|
||
|
||
INT va_test (RC_VAXVAR *precl, RC_VAXVAR *prec2);
|
||
|
||
|
||
Compare the two records pointed to by preci and prec2, returning 0 if the two records are equal, <0 if
|
||
*precl is before *prec2, or >0 if *preci is after *prec2
|
||
|
||
|
||
Each record is assumed to be an Rc_vaxvar struct whose buf field points to a PSEL_REC struct containing
|
||
either a file name or a directory name.
|
||
|
||
|
||
A directory name is always ordered before a file name and directory names are always ordered
|
||
alphabetically.
|
||
|
||
|
||
File names are ordered by one of name, creation time, creation date, size or extension, depending on the
|
||
PSEL_ORDER_XXx value stored in varoot .key. fold.
|
||
|
||
|
||
The result of the comparison is reversed if varoot .key.desc is non-zero.
|
||
|
||
|
||
PNODE
|
||
|
||
|
||
ACTIVE FACTIVE FNODE
|
||
q
|
||
|
||
|
||
owner flags
|
||
priority pname
|
||
isactive oldname
|
||
pcb pcb
|
||
stat
|
||
|
||
|
||
destroy fea-etese fnulist ao_abrun
|
||
|
||
|
||
ao_init ao_queue fn_end_list
|
||
ao_cancel | ao_run fn_nodename
|
||
aerab run fa_close
|
||
|
||
|
||
The pnove class subclasses the FNopE node and device list generator.
|
||
|
||
|
||
It is defined specifically for use by the psEt class, described later. The code contains assumptions that the
|
||
owner (whose handle is in factive.owner) is an instance of a subclass of pszEL and makes direct calls to
|
||
PSEL code.
|
||
|
||
|
||
The prope methods are designed only to be called via the mechanisms provided within the methods of the
|
||
PSEL Class, described later in this chapter.
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS pnode fnode
|
||
Used by psel to generate the node/directory array
|
||
{
|
||
REPLACE ao_abrun
|
||
REPLACE fn_end_list
|
||
REPLACE fn_nodename
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
15 -3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
PNODE methods
|
||
|
||
|
||
AO_ABRUN Handle error
|
||
|
||
|
||
VOID ao_abrun (VOID) ;
|
||
|
||
|
||
Supersend the ao_aprun message and then make a direct call to reset property and component objects of
|
||
the owner (assumed psEt).
|
||
|
||
|
||
FN_END LIST Handle completed list
|
||
|
||
|
||
VOID fn_end_list (VOID) ;
|
||
Process the completion of the node: :device:\ name list.
|
||
|
||
|
||
Reads and modifies the property of the owning (PsEL) object to indicate that the list has been changed,
|
||
and starts the generation of the file list corresponding to the selected, or the default, item in the
|
||
node: :device:\ list.
|
||
|
||
|
||
FN_NODENAME Process a list item
|
||
|
||
|
||
VOID fn_nodename (VOID) ;
|
||
Process a generated node: :device:\ name.
|
||
|
||
|
||
Makes a direct call to add the generated name to the owner's (psEL) directory/node name list and then
|
||
sends itself an Ao_QUEUE message to continue the scan.
|
||
|
||
|
||
PSEL
|
||
|
||
|
||
ACTIVE FACTIVE FSCAN
|
||
q
|
||
|
||
|
||
owner pfile
|
||
priority pdir
|
||
isactive pnode
|
||
pcb dirent
|
||
stat flags
|
||
ascent
|
||
dirnum
|
||
setpath
|
||
builderr
|
||
fck
|
||
fspec
|
||
|
||
|
||
fs_matchname ao_init
|
||
|
||
|
||
fs_fscan ao_abrun
|
||
|
||
|
||
ao_queue ao_cancel
|
||
|
||
ao_run fs_filename
|
||
|
||
fa_close fs_dirname
|
||
fs_fscan_end
|
||
ps_get_file
|
||
ps_ascend_path
|
||
ps_descend_path
|
||
|
||
|
||
fs_end_dirlist ps_set_path
|
||
|
||
|
||
ps_sense_filename
|
||
ps_select_direntry
|
||
ps_drives
|
||
ps_settag
|
||
ps_gettag
|
||
|
||
ps_order
|
||
|
||
|
||
ps_new_list
|
||
|
||
|
||
15-4
|
||
|
||
|
||
15 FILE LISTS
|
||
|
||
|
||
PSEL is an abstract subclass of rscan, providing methods to navigate a filing system and to generate both a
|
||
node list and a file name list from a wildcard file specification. In addition it provides methods to tag
|
||
items in its file name list and to retrieve such tagged items.
|
||
|
||
|
||
The node list contains device names or directory names at some specified level. The file name list contains
|
||
files and subdirectories within one particular item in the node list.
|
||
|
||
|
||
Although psx uses a number of active object components, it appears to a user as a single active object. A
|
||
queued request starts the building of one or more of its lists. On completion it reports:
|
||
|
||
|
||
e which lists have been changed
|
||
e whether the file specification has changed
|
||
|
||
|
||
e whether the file name list was either built successfully or was left empty because the physical
|
||
device does not exist (no disk in drive).
|
||
|
||
|
||
A subclass of psex is used, for example, to generate and navigate the file lists displayed in the file
|
||
commands of the Series 3 System application, and in the MC File Manager application.
|
||
|
||
|
||
Subclasses of psEL are not expected to replace any of the supplied methods.
|
||
|
||
|
||
Note that there is no automatic detection of filing system changes. This means that a file list will be out of
|
||
date if, for example, another process has created a file in the directory being displayed after the file list
|
||
was last built. A regeneration of the file name list may be forced by sending a ps_sET_PATH message.
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS psel fscan
|
||
Builds a node/directory array and a file array from a wild card path
|
||
{
|
||
REPLACE ao_init
|
||
REPLACE ao_abrun
|
||
REPLACE ao_cancel
|
||
REPLACE fs_filename
|
||
REPLACE fs_dirname
|
||
REPLACE fs_fscan_end
|
||
DD ps_get_file
|
||
ps_ascend_path
|
||
ps_descend_path
|
||
ps_set_path
|
||
ps_sense_filename
|
||
ps_select_direntry
|
||
ps_drives
|
||
ps_settag
|
||
ps_gettag
|
||
DD ps_order
|
||
DEFER ps_new_list
|
||
|
||
|
||
D
|
||
D
|
||
D
|
||
D
|
||
D
|
||
D
|
||
D
|
||
D
|
||
|
||
|
||
pPppprprprpr pe
|
||
|
||
|
||
CONSTANTS
|
||
{
|
||
PSEL_RESET_DIR_ARRAY 0x01 True if NOT reset node/dir array
|
||
PSEL_RESET_FILE_ ARRAY 0x02 True if NOT reset files array
|
||
PSEL_RESET_FSPEC 0x04 True if NOT reset fspec[]
|
||
PSEL_DEVICE_ARRAY 0x10 Building device list
|
||
PSEL_DIR_ARRAY 0x20 Building dir list
|
||
PSEL_FILE_ ARRAY 0x40 Building file list
|
||
PSEL_DESCEND 0x80 Building due to a descend
|
||
PSEL_ASCEND 0x100 Building due to an ascend
|
||
PSEL_SETPATH 0x200 Building due to a set path
|
||
PSEL_INIT 0x400 Building due to an init
|
||
PSEL_SELDIR 0x800 Building due to select dir
|
||
PSEL_ANOTHER_CMD 0x1000
|
||
PSEL_GENERATE_DEF 0x2000
|
||
PSEL_QUEUED_CMD 0x4000 Running a queued cmd
|
||
PSEL_CURRENTLY_BUSY (0x100|0x80|0x400|0x200|0x800)
|
||
PSEL_SET_TAG =
|
||
PSEL_CLEAR_TAG 0
|
||
PSEL_TOGGLE_TAG 1
|
||
|
||
|
||
}
|
||
|
||
|
||
15-5
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
PROPERTY 3
|
||
{
|
||
PR_PSELVAR *pfile; File name lists
|
||
PR_VASTR *pdir; Directory/Node name list
|
||
PR_PNODE *pnode; Node List Generator
|
||
UWORD Which directory in list should be highlighted
|
||
|
||
|
||
UWORD
|
||
UWORD
|
||
UWORD
|
||
|
||
|
||
File selector control flags
|
||
|
||
|
||
UBYTE *setpath;
|
||
|
||
|
||
WORD builderr;
|
||
P_FPARSE fck;
|
||
|
||
|
||
Files list build error to report
|
||
Currently cracked wildcard file spec
|
||
|
||
|
||
TEXT fspec[P_FNAMESIZE]; Current wildcarded file spec
|
||
|
||
|
||
}
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
psel.
|
||
|
||
|
||
15 - 6
|
||
|
||
|
||
pfile
|
||
|
||
|
||
pdir
|
||
|
||
|
||
pnode
|
||
|
||
|
||
dirent
|
||
|
||
|
||
flags
|
||
|
||
|
||
ascent
|
||
|
||
|
||
dirnum
|
||
|
||
|
||
setpath
|
||
|
||
|
||
builderr
|
||
|
||
|
||
fck
|
||
|
||
|
||
fspec
|
||
|
||
|
||
the handle of an instance of pszLvar, which holds the file name list in an
|
||
array of psEL_ReEc records. A subclass may access this handle, and will
|
||
typically pass it to display code. (Note that pszLvar's va_pBur method
|
||
returns a pointer to a PSEL_RECc struct, rather than to the text of a file
|
||
name.)
|
||
|
||
|
||
the handle of an instance of vastr, which holds the array of names for a
|
||
node or directory list. A subclass may access this handle and will typically
|
||
pass it to display code.
|
||
|
||
|
||
the handle of an instance of pNopz, which generates a node: :device:\
|
||
name list. It should not be accessed by a subclass.
|
||
|
||
|
||
the index of the current node list item in the psel.pdir VASTR array. It
|
||
defines the subdirectory for which the file list is built (a value of -1
|
||
indicates that no entry is current). A subclass may read this field to
|
||
indicate which displayed node list entry to highlight.
|
||
|
||
|
||
controlling flags used to drive the psx object. A subclass may read the
|
||
values of the pSEL_RESET_DIR_ARRAY, PSEL_RESET_FILE_ARRAY and
|
||
PSEL_RESET_FSPEC bit-fields.
|
||
|
||
|
||
the outstanding number of directory ascends to be performed (a user may
|
||
request multiple ascends faster than they can be serviced). It should not be
|
||
accessed by a subclass.
|
||
|
||
|
||
the index of the most recently selected entry from the psel.pdir VASTR
|
||
array. Typically the user interface will allow the selection of a new entry
|
||
from this array while eset is busy building the file names array for a
|
||
previously selected entry. It should not be accessed by a subclass.
|
||
|
||
|
||
a pointer to the most recently selected wildcarded file name specification
|
||
from which the node and file name arrays are to be built. The data space
|
||
to which it points must be preserved until the arrays have been fully built.
|
||
It should not be accessed by a subclass.
|
||
|
||
|
||
an error number corresponding to a drastic error (such as out of memory,
|
||
or the removal of a filing system) which occurred while building the node
|
||
and file name arrays. If no error has occurred the value will be zero. A
|
||
subclass is expected to test this value to determine the build completion
|
||
result when the deferred ps_new_List method is called.
|
||
|
||
|
||
the parsed file name information for the wildcarded name (contained in
|
||
psel.fspec) that is currently being used to build the node and file name
|
||
arrays. A subclass should treat this as a read-only field.
|
||
|
||
|
||
the wildcarded file name specification that drives the generation of the
|
||
node and file name arrays. Typically this field could be used to display the
|
||
full file name specification corresponding to the arrays that have just been
|
||
built. A subclass should treat this as a read-only field.
|
||
|
||
|
||
15 FILE LISTS
|
||
|
||
|
||
PSEL methods
|
||
|
||
|
||
A user is expected to send only those explicit messages that appear in the following list:
|
||
|
||
|
||
PS_ASCEND_PATH ascend one subdirectory level
|
||
PS_DESCEND_PATH descend to a subdirectory
|
||
PS_SET_PATH set a new path
|
||
PS_SENSE_FILENAME sense a file list item
|
||
PS_SELECT_DIRENTRY select a node list entry
|
||
PS_DRIVES ascend to the drives level
|
||
PS_SETTAG set/clear a file tag
|
||
|
||
PS_GETTAG get a tagged file
|
||
|
||
PS_ORDER set the file list order
|
||
|
||
The remaining methods are intended for internal use.
|
||
Many of the above methods cause either or both of the directory/node and file name lists to be rebuilt. If
|
||
|
||
|
||
this fails (say, because the pack has been removed or the filing system no longer exists) then the lists are
|
||
rebuilt at the node: :device:\ level. All such methods result in a (deferred) ps_NEw_LIsT message being
|
||
sent. Depending on whether rebuilding is required, this message may be sent either before the method
|
||
returns or at some later time, when building is complete.
|
||
|
||
|
||
AO_INIT Initialise
|
||
|
||
|
||
VOID ao_init (TEXT *pname) ;
|
||
|
||
|
||
Supersends an ao_1n1T message to add itself to the appman queue and then creates and initialises the
|
||
psel.pdir, psel.pfile (with a granularity of 32) and psel.pnode components.
|
||
|
||
|
||
Then starts building the node and file name arrays, using the text pointed to by pname as the initial file
|
||
name specification.
|
||
|
||
|
||
If the initial file specification is not valid (say, because the filing system no longer exists) the default lists
|
||
are built. These consist of:
|
||
|
||
|
||
e anode list containing all currently available node: :device:\ names
|
||
|
||
|
||
e a file name list for the directory indicated by the first item in the node list, containing all files
|
||
that match the initial file name specification.
|
||
|
||
|
||
Calls p_leave on error (out of memory).
|
||
|
||
|
||
AO_ABRUN Handle error
|
||
|
||
|
||
VOID ao_abrun (VOID) ;
|
||
Handle an error arising during the processing of an ao_RUN message.
|
||
|
||
|
||
Discards the contents of the node and file name lists (at least one of which is likely to be only partially
|
||
built) and sets psel. fspec to contain a null string.
|
||
|
||
|
||
Sends a ps_NEW_LIST message, which will normally cause the user interface to display empty lists and
|
||
then supersends the ao_aBRuN message.
|
||
|
||
|
||
This method will only be invoked by out of memory errors or by the disappearance of filing systems
|
||
during the generation of the lists.
|
||
|
||
|
||
& AO CANCEL Cancel list building
|
||
|
||
|
||
VOID ao_cancel (VOID);
|
||
|
||
|
||
Sends an ao_cAaNCEL tO psel.pnode to cancel any request on the node list generator and then supersends
|
||
an AO_CANCEL to cancel any file scan request. These two messages ensure that any open channels are
|
||
closed. Following this, the contents of the node and file name lists are discarded.
|
||
|
||
|
||
This method is intended only to be executed as a consequence of psEL receiving a DESTROY message. A
|
||
user should not, for example, send an ao_caNcEL message when requesting an operation (such as an
|
||
ascend) before a previous operation has completed. Such a sequence is handled by pset's internal logic
|
||
and the user should simply request the new operation.
|
||
|
||
|
||
15-7
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
FS_FILENAME Add a file name
|
||
|
||
|
||
VOID fs_filename (VOID) ;
|
||
Add a file name to the file name list.
|
||
|
||
|
||
Generates a psEL_rec for the file name pointed to by fscan.pname and appends it to the file name list (the
|
||
list will be ordered when it is complete).
|
||
|
||
|
||
Note that, to minimise memory use, the psEL_REc struct is adjusted to the exact length required for its
|
||
content before it is appended. You should also be aware that the contents of the namien field of the
|
||
PSEL_REC Struct will only be valid if the file name list is sorted by extension.
|
||
|
||
|
||
If the name is added successfully, sends an ao_quEUE message to continue the scan.
|
||
|
||
|
||
May call p_leave (E_GEN_NOMEMORY) .
|
||
|
||
|
||
FS DIRNAME Add a directory name
|
||
|
||
|
||
VOID fs_dirname (VOID) ;
|
||
|
||
|
||
Add a directory name to either the node list or the file name list depending on which list is currently being
|
||
built.
|
||
|
||
|
||
If the name is being added to the node list, the full name (taken from the start of the fscan.name buffer) is
|
||
inserted in alphabetical order.
|
||
|
||
|
||
If it is being added to the file name list, only the ‘file name' part (pointed to by fscan.pname) is appended
|
||
to the list exactly as described for the f£s_filename method.
|
||
|
||
|
||
If the name is added successfully, sends an ao_quzuE message to continue the scan.
|
||
|
||
|
||
May call p_leave (E_GEN_NOMEMORY) .
|
||
|
||
|
||
FS FSCAN_END Process end of a scan
|
||
|
||
|
||
VOID fs_fscan_end(VOID) ;
|
||
Process the end of the building of either the node list or the file name list.
|
||
If the node list has just been built, the building of the appropriate file name list is started.
|
||
|
||
|
||
If the node list has not changed (say, because the build was initiated by a directory ascend request when
|
||
already at the drives level), the processing is as for the completion of the building of the file name list,
|
||
described below.
|
||
|
||
|
||
If the file name list has just been built, a check is made to see if any additional requests (such as one or
|
||
more directory ascends) have been made while the list was being built. If so, the appropriate list building
|
||
is restarted. Otherwise, provided the file name list has changed, it is sorted in the currently specified order
|
||
and a ps_NEW_LIST message is sent to indicate that list building is complete.
|
||
|
||
|
||
PS GET _ FILE Build file name list
|
||
|
||
|
||
INT ps_get_file (VOID);
|
||
|
||
|
||
Discard the current file name list and send an rs_rscan message to start a scan to build a new list for the
|
||
directory specified by the current item in the node list. The list will include all subdirectories, together
|
||
with all file names that match the wildcard file name and extension string contained within the full file
|
||
specification in the psel. fspec buffer.
|
||
|
||
|
||
Returns zero, indicating a successful start of the scan.
|
||
|
||
|
||
Calls p_1eave on error.
|
||
|
||
|
||
15-8
|
||
|
||
|
||
15 FILE LISTS
|
||
|
||
|
||
& PS ASCEND PATH Ascend one subdirectory level
|
||
|
||
|
||
VOID ps_ascend_path (VOID);
|
||
|
||
|
||
Start the rebuilding of the node and file name lists for a directory level one higher than that specified by
|
||
the wildcarded full file specification in pse1.fspec.
|
||
|
||
|
||
If the current directory level is at the node: :device:\ level already (if, for example, psel.fspec contains
|
||
"LOC::A:\*.1MG") then no further ascends can be made. The node list will, however, be re-built because a
|
||
filing system may have been added or removed since the last time the lists were built. This is the only way
|
||
in which such a change in the filing system can be recorded in the node list.
|
||
|
||
|
||
In such a case the files list will not be re-built unless the current node has disappeared.
|
||
|
||
|
||
If this message is received while the lists are in process of being built then the ascend request will be
|
||
stored internally. On completion of the current build, building will be restarted (without sending a
|
||
PS_NEW_LIST message) at the new directory level.
|
||
|
||
|
||
& PS DESCEND PATH Descend to a subdirectory
|
||
|
||
|
||
VOID ps_descend_path(UINT entryno) ;
|
||
|
||
|
||
Descend into the subdirectory specified by record number entryno in the file name list and start the
|
||
rebuilding of the node and file name lists.
|
||
|
||
|
||
Does nothing if the lists are currently being built (since the array from which the entry was selected no
|
||
longer exists).
|
||
|
||
|
||
An entryno of -1 (meaning that no list item was selected) has the same effect as a value of 0, specifying
|
||
the first item.
|
||
|
||
|
||
The file name list is checked to ensure that it contains the entry number specified and that the
|
||
corresponding record is the name of a directory. If either of these tests fail the method does nothing.
|
||
|
||
|
||
Otherwise the node and file name lists are rebuilt for the new directory level.
|
||
|
||
|
||
& PS SET PATH Set a new path
|
||
|
||
|
||
VOID ps_set_path(TEXT *pname) ;
|
||
|
||
|
||
Start the rebuilding of the node and file name lists to correspond with the wildcard full file specification
|
||
pointed to by pname.
|
||
|
||
|
||
If the lists are currently being built, the new path name pointer is stored until the appropriate time that the
|
||
current build can be abandoned and a new build started.
|
||
|
||
|
||
In all cases the data space pointed to by pname must be preserved until a ps_NEW_LIST message is received
|
||
to indicate that the lists have been rebuilt.
|
||
|
||
|
||
& PS SENSE FILENAME Sense a file list item
|
||
|
||
|
||
INT ps_sense_filename (INT entryno, PSEL_REC **pprec) ;
|
||
Write, to *pprec, a pointer to the pszEL_ReEc data for the file list item with record number entryno.
|
||
|
||
|
||
Returns zero if successful. Does not write to *pprec and returns E_FILE_LOCKED if the list is currently
|
||
being built.
|
||
|
||
|
||
& PS SELECT DIRENTRY Select a node list entry
|
||
|
||
|
||
VOID ps_select_direntry (INT entryno) ;
|
||
Start the building of the file name list for the directory specified by item number ent ryno in the node list.
|
||
|
||
|
||
If a file name list is currently being built as a result of an earlier ps_sELECT_DIRENTRY message, the
|
||
current activity is aborted and the build is restarted for the new list. This provides a rapid response to
|
||
repeated ps_SELECT_DIRENTRY messages received from the user interface (generated, for example, as the
|
||
user moves a highlight up and down a displayed list). If a list is being built for any other reason, the
|
||
PS_SELECT_DIRENTRY message has no effect.
|
||
|
||
|
||
15-9
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
© PS DRIVES Ascend to the drives level
|
||
|
||
|
||
VOID ps_drives (VOID) ;
|
||
|
||
|
||
Start the rebuilding of the node and file name lists to generate a node list containing node: :device:\ names
|
||
and a file name list containing those items which match the file name and extension contained in the
|
||
wildcarded full file specification in the psel. fspec buffer.
|
||
|
||
|
||
Does nothing if the lists are currently being built.
|
||
If the lists are currently at the drives level then they are not rebuilt.
|
||
|
||
|
||
In either case a PS_NEW_LIST message will be sent to indicate that the list building is complete.
|
||
|
||
|
||
& PS _SETTAG Set/clear a file tag
|
||
|
||
|
||
INT ps_settag(INT entryno, INT flag);
|
||
|
||
|
||
Set, clear or toggle the tag status (held in the flags field of the pszL_rxEc struct) of the file name list item
|
||
specified by entryno.
|
||
|
||
|
||
The tag status will be set if f1ag is ps—EL_sET_TAG, Cleared if f1ag is PSEL_CLEAR_TAG and toggled if flag
|
||
iS PSEL_TOGGLE_TAG.
|
||
|
||
|
||
Returns True if the tag status has been set, and rause if it has been cleared.
|
||
|
||
|
||
& PS _GETTAG Get a tagged file
|
||
|
||
|
||
INT ps_gettag(INT index, PSEL_REC **pprec) ;
|
||
|
||
|
||
Write, to *pprec, a pointer to the psEL_REc of an item in the file name list that has its tag status set, and
|
||
return either a (positive) value to be used as the index for a subsequent ps_GETTAG message, or
|
||
E_FILE_EOF if there are no further tagged entries.
|
||
|
||
|
||
If index is zero, the value written to *pprec points to the first tagged item. If index is the value returned
|
||
by the previous ps_cettac the value written to *pprec is a pointer to the next tagged item.
|
||
|
||
|
||
This method allows the extraction of the names of all tagged files, one by one.
|
||
|
||
|
||
PS ORDER Set the file list order
|
||
|
||
|
||
VOID ps_order(INT mode, INT reverse);
|
||
|
||
|
||
Set the current file name list order and sort the entries. The value of mode should be one of:
|
||
|
||
|
||
PSEL_ORDER_NAME order alphabetically by full name (the default)
|
||
PSEL_ORDER_TIME order by time of creation
|
||
|
||
PSEL_ORDER_DATE order by date of creation
|
||
|
||
PSEL_ORDER_SIZE order by size of file
|
||
|
||
PSEL_ORDER_EXT order alphabetically by extension
|
||
|
||
|
||
If reverse is TRUE the ordering is reversed.
|
||
|
||
|
||
The current file name list is regenerated in the new order. If the ordering is not by extension the
|
||
reordering will be completed before this method returns. Otherwise the method starts a build of the file
|
||
name list in the specified order and this will complete at some future time. In either case an ps_NEW_LIST
|
||
message is sent when the list is complete.
|
||
|
||
|
||
All subsequent builds of the file name list will be performed in the specified order, until it is changed by a
|
||
further ps_oRDER message.
|
||
|
||
|
||
By default the file name list is built in ascending alphabetical name order.
|
||
|
||
|
||
15 - 10
|
||
|
||
|
||
15 FILE LISTS
|
||
|
||
|
||
Deferred PSEL methods
|
||
& PS NEW _LIST Process the completion of list building
|
||
|
||
|
||
VOID ps_new_list (VOID) ;
|
||
|
||
|
||
A deferred method which is always received on completion of any request to build or reorder the node
|
||
and/or file name arrays. It may be received either before the build request returns or at a later time,
|
||
depending on whether any lists need to be rebuilt.
|
||
|
||
|
||
The supplier of this method is expected to test psel.blderr to determine the result of the build, and may
|
||
also read psel.flags, psel.pfile, psel.pdir, psel.dirent, psel.fck and psel.fspec, aS explained in
|
||
the descriptions of the property fields.
|
||
|
||
|
||
A typical action would be to regenerate the data displayed in the user interface. It should examine
|
||
psel.flags and:
|
||
|
||
|
||
e if PSEL_RESET_DIR_ARRAY iS FALSE, regenerate the display of the directory/node names from the
|
||
psel.pdir array
|
||
|
||
|
||
e if PSEL_RESET_FILE_ARRAY iS FALSE, regenerate the display of the file names from the
|
||
psel.pfile array
|
||
|
||
|
||
e if PSEL_RESET_FSPEC iS FALSE, regenerate the display of the file name specification from the
|
||
psel.fspec buffer
|
||
|
||
|
||
This method is expected to return. Any code that may result in p_leave being called must be run under
|
||
the protection of p_enter.
|
||
|
||
|
||
15-11
|
||
|
||
|
||
CHAPTER 16
|
||
|
||
|
||
FILE MANAGEMENT CLASSES
|
||
|
||
|
||
The classes described in this chapter, and in particular the rman class, supply the basic engine for
|
||
performing file management. They provide a set of high-level file system operations, for example, to copy
|
||
a set of files, delete a directory structure or format an SSD.
|
||
|
||
|
||
FMAN creates and uses component instances of the FMMK, FMFMT, FMSCAN, FMSRC and FMTARG active object
|
||
classes (which are all subclasses of FACTIVE). These components do the bulk of the work and, by breaking
|
||
a potentially lengthy operation into small sections, ensure that the application remains responsive to
|
||
window server events. Note that only one of these components is active at any one time.
|
||
|
||
|
||
The classes are strongly interdependent. rman reads from and writes to the property of the other classes,
|
||
which themselves rely on their being owned components of Fuan.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e the active object scheduling mechanisms in the application manager
|
||
e the FACTIVE, Fscan and Fcasy classes
|
||
e the PLIB file system services
|
||
e =the p_enter and p_leave error handling services
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
tee
|
||
¢ active /
|
||
a me
|
||
=
|
||
ie factive
|
||
cee AES “y
|
||
ez )
|
||
-, aa ae _ to —~ ze 7 ae )
|
||
wo —— Te ie rea
|
||
Gas M t Gataee Se fmscan /
|
||
= )
|
||
err
|
||
|
||
|
||
16-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
FMAN
|
||
|
||
|
||
srcfile
|
||
|
||
|
||
targfile
|
||
|
||
|
||
fmscan
|
||
fmmk
|
||
fmfmt
|
||
action
|
||
mode
|
||
|
||
|
||
fman_init
|
||
fman_cancel
|
||
fman_copy
|
||
|
||
|
||
srclen
|
||
dispinfo
|
||
targname
|
||
wildsrcname
|
||
wildtargname
|
||
buf
|
||
|
||
|
||
fman_name
|
||
fman_info
|
||
|
||
|
||
fman_attrib
|
||
|
||
|
||
fman_delete
|
||
fman_rename fman_complete
|
||
fman_make fman_newname
|
||
fman_remove fman_update
|
||
fman_copydev fman_fileexist
|
||
|
||
|
||
fman_format fman_error
|
||
|
||
|
||
The rman (file manager) abstract class provides a set of file management operations. It must be subclassed
|
||
to supply the deferred methods (which are chosen to provide a flexible interaction with any user interface)
|
||
in order to create a useful object. It is not expected that a subclass will replace any of the supplied
|
||
methods.
|
||
|
||
|
||
An FMaN operation is initiated by sending the appropriate message from the following list:
|
||
|
||
|
||
FMAN_COPY copy files
|
||
|
||
FMAN_DELETE delete files
|
||
|
||
FMAN_RENAME rename files
|
||
|
||
FMAN_MAKE make a directory
|
||
|
||
FMAN_REMOVE remove a directory (and its subdirectories)
|
||
FMAN_COPYDEV copy a device
|
||
|
||
FMAN_FORMAT format a device
|
||
|
||
FMAN_NAME name a device
|
||
|
||
FMAN_ATTRIB set file attributes
|
||
|
||
|
||
Each of these methods will call p_1eave on error. If successful in initiating the required action, some of
|
||
these methods return zero, while others call p_1eave (0) (to simplify the centralisation of error handling).
|
||
It is therefore essential to send these messages under the protection of a p_enter (you could, for example,
|
||
send the message by means of p_entersena). Under such protection the methods which call p_1eave (0)
|
||
will behave equivalently to those methods which return zero.
|
||
|
||
|
||
Any operation may complete before the send of the initialising message has returned. Normally, however,
|
||
each of these operations will involve at least one active object (typically rmscan) which at some future
|
||
time will be sent at least one ao_run message. Thus the operation will usually complete long after the send
|
||
of the initiating message has returned.
|
||
|
||
|
||
Regardless of when it occurs, the completion may represent the successful conclusion of the operation, or
|
||
may result from the operation being cancelled, either at the user's request or as the result of an error
|
||
condition. Every completion, for whatever reason, results in the subclass of rman receiving one, and only
|
||
one, FMAN_COMPLETE message. This is typically used to destroy any visual indicator of the current
|
||
operation that is being presented to the user.
|
||
|
||
|
||
16-2
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fman root
|
||
The File Manager
|
||
{
|
||
ADD fman_init Create/Init the active objects
|
||
ADD fman_cancel Cancel the last request
|
||
ADD fman_copy Copy files
|
||
ADD fman_delete Delete files
|
||
ADD fman_rename Rename files
|
||
ADD fman_make Make a directory
|
||
ADD fman_remove Remove a dir structure
|
||
ADD fman_copydev Copy a device
|
||
ADD fman_format Format a device
|
||
ADD fman_name Name a Pack
|
||
ADD fman_info=p_dummy For define of O_FMAN_INFO at least
|
||
ADD fman_attrib Set file attributes
|
||
DEFER fman_complete Operation now complete
|
||
DEFER fman_newname Operation now on this file(s)
|
||
DEFER fman_update Update copying display
|
||
DEFER fman_fileexist Destination file exists
|
||
DEFER fman_error Error in operation, abort/continue
|
||
CONSTANTS
|
||
{
|
||
FMAN_READ_SIZE 0x800 Copy 2k at a time
|
||
FMAN_COPYING 0
|
||
FMAN_DELETE 1
|
||
FMAN_RENAME 2
|
||
FMAN_MAKE 3
|
||
FMAN_REMOVE 4
|
||
FMAN_FORMAT 5
|
||
FMAN_NAME 6
|
||
FMAN_ATTRIB 7)
|
||
}
|
||
PROPERTY 5
|
||
{
|
||
PR_FMSRC *srcfile; Src/Read file active object
|
||
PR_FMTARG *targfile; Target/Write file active object
|
||
PR_FMSCAN *fmscan; File system scan active object
|
||
PR_FMMK *fmmk; Make Dir active object
|
||
PR_FMFMT *fmfmt; Format a pack.
|
||
UWORD action; Current file manager action
|
||
UWORD mode; Current file create/replace mode
|
||
UWORD srclen;
|
||
FCOPY_DISP dispinfo; Display info
|
||
UBYTE targname [P_FNAMESIZE]; Fully spec'ted target name
|
||
UBYTE wildsrcname[P_FNAMESIZE]; Entered wildcarded srcname
|
||
UBYTE wildtargname[P_FNAMESIZE]; Entered wildcarded target
|
||
UBYTE buf [FMAN_READ_SIZE];
|
||
}
|
||
}
|
||
Property
|
||
fman.srcfile the handle of an instance of rusrc, representing the source file during a
|
||
file copy. It should not be accessed by any subclass.
|
||
fman.targfile the handle of an instance of rmtare, representing the target file during a
|
||
file copy. It should not be accessed by any subclass.
|
||
fman. fmscan the handle of an instance of rmscan, used to generate the lists of files upon
|
||
which an operation acts. It should not be accessed by any subclass.
|
||
fman. fmmk the handle of an instance of rmmx, used to create a directory structure. It
|
||
should not be accessed by any subclass.
|
||
fman. £mfmt the handle of an instance of rvrut, used to format an SSD. It should not
|
||
|
||
|
||
be accessed by any subclass.
|
||
|
||
|
||
16 -3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
fman.action the current file manager action, used to determine what operation to
|
||
perform on a name generated by rmscan. It takes one of the following
|
||
values:
|
||
|
||
|
||
FMAN_COPYING - copying files
|
||
|
||
FMAN_DELETE - deleting files
|
||
|
||
FMAN_RENAME - we are renaming files
|
||
FMAN_ATTRIB - Changing the file attributes
|
||
FMAN_MAKE - creating a directory structure
|
||
FMAN_REMOVE - removing a directory structure
|
||
FMAN_FORMAT - formatting an SSD
|
||
|
||
FMAN_NAME - naming an SSD
|
||
|
||
|
||
It should not be accessed by any subclass, but see also fman.dispinfo,
|
||
which also contains this data.
|
||
|
||
|
||
fman.mode the current create/replace mode for a file copy operation, At the start of a
|
||
copy it is set to create the copy file(s) but may later be modified,
|
||
depending on the result of an rMaN_FILEEXxIsT message. It should not be
|
||
accessed by any subclass.
|
||
|
||
|
||
fman.srclen how many bytes to read from a source file, and the length of buffered data
|
||
to write to a target file. It should not be accessed by any subclass.
|
||
|
||
|
||
fman.dispinfo information describing the current file manager action (see the
|
||
fman_newname method for details of the rcopy_p1sp struct). It is intended
|
||
to be used to provide information about the current operation for the user
|
||
interface. It should only be read from within the fman_newname method.
|
||
|
||
|
||
fman.targname the generated full file specification of a target file. It should not be
|
||
accessed by any subclass.
|
||
|
||
|
||
fman.wildsrcname the wildcarded file name passed as the source file name in one of the
|
||
messages that initiates an operation. It should not be accessed by any
|
||
subclass.
|
||
|
||
fman.wildtargname the wildcarded file name passed as the target file name in one of the
|
||
|
||
|
||
messages that initiates an operation between two files. It should not be
|
||
accessed by any subclass.
|
||
|
||
|
||
fman.buf the data read from the source file and written to the target file during a
|
||
file copy. It should not be accessed by any subclass.
|
||
|
||
|
||
FMAN methods
|
||
|
||
|
||
FMAN_INIT Initialise the file manager
|
||
|
||
|
||
VOID fman_init (VOID) ;
|
||
|
||
|
||
Create and initialise the five active objects whose handles are stored in the first five items of rman's
|
||
property. The initialisation of each registers rman as its owner and adds the active object to the application
|
||
manager's active object task queue.
|
||
|
||
|
||
Calls p_1leave (E_GEN_NOMEMoRy) on failure.
|
||
|
||
|
||
FMAN_CANCEL Cancel an outstanding request
|
||
|
||
|
||
VOID fman_cancel (VOID) ;
|
||
|
||
|
||
Cancel any current file operation, sending ao_cANCEL messages to the appropriate active object
|
||
components, depending on the value of fman. action.
|
||
|
||
|
||
Following this, an FMAN_COMPLETE message Is sent to indicate that the current operation has been
|
||
completed.
|
||
|
||
|
||
16-4
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
FMAN_COPY Copy files
|
||
|
||
|
||
VOID fman_copy(UBYTE *src, UBYTE *targ, INT flags);
|
||
|
||
|
||
Start the copy of files specified by the wildcarded source file name at src to the wildcarded target name at
|
||
targ.
|
||
|
||
|
||
Before the copy is started, the source and target file names are validated:
|
||
|
||
|
||
e The source file name must not be a null string and it must be a name acceptable to the p_fparse
|
||
function (the name is parsed with "*" as the related name and the resulting full file specification
|
||
is written into fman.wildsrcname).
|
||
|
||
|
||
e If the target name is a null string, it is replaced by the file name and extension taken from the full
|
||
file specification in fman.wildsrcname. The target name is parsed with a nux related name into
|
||
fman.wildtargname. A final check is made that the resulting source and target file names are not
|
||
identical.
|
||
|
||
|
||
If the validation generated the target name from the source name (because targ points to a null string) the
|
||
name and extension in fman.wildtargname are replaced by "*".
|
||
|
||
|
||
Following this, fman.dispinfo.protocol and fman.action are both set to rman_copyinec and
|
||
fman.dispinfo.blksiz iS set tO FMAN_READSIZE, With fman.dispinfo. flags set to indicate that the
|
||
appropriate fields are valid.
|
||
|
||
|
||
The value of fman.mode 1s Set to P_FCREATE|P_FSTREAM, SO that, initially, the copy files will be created (as
|
||
opposed to, say, replacing existing files).
|
||
|
||
|
||
The flags parameter should contain a bitwise combination of one or more of the following values, defined
|
||
in factive. g:
|
||
|
||
FS_ALL_FILES include all non-directory files that are neither hidden nor system files
|
||
FS_WRITABLE aS FS_ALL_FILES, but excludes write-protected files (see below)
|
||
|
||
FS_HIDDEN include hidden files
|
||
|
||
FS_SYSTEM include system files
|
||
|
||
FS_DIRECTORIES include directory files
|
||
|
||
FS_MODIFIED exclude unmodified files (include only files that have p_ramop set)
|
||
FS_INCLUDE_SUBDIRECTORIES extend the scan to subdirectories
|
||
|
||
FS_PARSE_NAME parse file names before reporting them
|
||
|
||
|
||
The rmscan component has fscan. flags set to the passed flags value, ored with rs_HIDDEN|FS_SYSTEM,
|
||
and fscan.match is set to point to the name and extension within the fman.wildsrcname buffer. An
|
||
FS_FSCAN message is then sent to the rmscan component to generate the list of files to copy. The initial
|
||
start up file name passed with this message is the full contents of fman.wildsrcname.
|
||
|
||
|
||
Any error encountered during the file name validation or in rMscan's rs_Fscan method results in p_leave
|
||
being called with an appropriate error.
|
||
|
||
|
||
On successful completion the method calls p_leave (0). The rman_copy message must therefore be sent
|
||
under the protection of a p_enter.
|
||
|
||
|
||
Further processing of the file copy is handled by the rmscan component.
|
||
|
||
|
||
FMAN_DELETE Delete files
|
||
|
||
|
||
VOID fman_delete(UBYTE *src, INT flags);
|
||
|
||
|
||
Start the deletion of one or more files as specified by the wildcarded file specification string pointed to by
|
||
src. In contrast to the fman_remove method, directories are not deleted.
|
||
|
||
|
||
Before the deletion is started the file specification string is validated. It must not be a null string and it
|
||
must be a name acceptable to the p_fparse function (the name is parsed with "«" as the related name and
|
||
the resulting full file specification is written into fman.wildsrcname).
|
||
|
||
|
||
Following this, fman.dispinfo.protocol and fman.action are both set to rMaN_DELETE. The value of
|
||
fman.dispinfo. flags is Set to indicate that the appropriate field is valid.
|
||
|
||
|
||
16-5
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
The flags parameter should contain a bitwise combination of one or more of the following values, defined
|
||
in factive. g:
|
||
|
||
FS_ALL_FILES include all non-directory files that are neither hidden nor system files
|
||
FS_WRITABLE aS FS_ALL_FILES, but excludes write-protected files (see below)
|
||
|
||
FS_HIDDEN include hidden files
|
||
|
||
FS_SYSTEM include system files
|
||
|
||
FS_DIRECTORIES include directory files
|
||
|
||
FS_MODIFIED exclude unmodified files (include only files that have p_ramop set)
|
||
FS_INCLUDE_SUBDIRECTORIES extend the scan to subdirectories
|
||
|
||
FS_PARSE_NAME parse file names before reporting them
|
||
|
||
|
||
The rmscan component has fscan. flags set to the passed flags value, ored with rs_HIDDEN|FS_SYSTEM,
|
||
and fscan.match is set to point to the name and extension within the fman.wildsrcname buffer. An
|
||
FS_FSCAN message is then sent to the rmscan component to generate the list of files to delete. The initial
|
||
start up file name passed with this message is the full contents of fman.wildsrcname.
|
||
|
||
|
||
Any error encountered during the file name validation or in rmscan's rs_Fscan method results in p_leave
|
||
being called with an appropriate error.
|
||
|
||
|
||
On successful completion, the method calls p_leave (0). The rMaAN_DELETE message must therefore be sent
|
||
under the protection of a p_enter.
|
||
|
||
|
||
Further processing of the file deletion is handled by the rmscan component.
|
||
|
||
|
||
FMAN_RENAME Rename files
|
||
|
||
|
||
VOID fman_rename (UBYTE *src, UBYTE *targ);
|
||
|
||
|
||
Start the renaming of one or more files as specified by the wildcarded file specification string pointed to
|
||
by src to names specified by the wildcarded file specification string pointed to by targ.
|
||
|
||
|
||
Before the rename is started the source and target file names are validated:
|
||
|
||
|
||
e The source file name must not be a null string and it must be a name acceptable to the p_fparse
|
||
function (the name is parsed with "*" as the related name and the resulting full file specification
|
||
is written into fman.wildsrcname).
|
||
|
||
|
||
e If the target name is a null string it is replaced by the file name and extension taken from the full
|
||
file specification in fman.wildsrcname. The target name is parsed with a nut related name into
|
||
|
||
|
||
fman.wildtargname.
|
||
|
||
|
||
Final checks are made that the resulting source and target file names are not identical, and that both file
|
||
specifications refer to the same directory (files can not be renamed across directories, devices or file
|
||
systems).
|
||
|
||
|
||
If the validation generated the target name from the source name (because targ points to a null string),
|
||
the name and extension in fman.wildtargname are replaced by "*".
|
||
|
||
|
||
Following this, fman.dispinfo.protocol and fman.action are both set to FMAN_RENAME. The value of
|
||
fman.dispinfo. flags is set to indicate that the appropriate field is valid.
|
||
|
||
|
||
The rmscan component has fscan. flags Set t0 FS_ALL_FILES|FS_HIDDEN|FS_sysTEM and fscan.match IS
|
||
set to point to the name and extension within the fman.wildsrcname buffer. An rs_rscan message is then
|
||
sent to the rmscan component to generate the list of files to rename. The initial start up file name passed
|
||
with this message is the full contents of fman.wildsrcname.
|
||
|
||
|
||
Any error encountered during the file name validation or in rmscan's rs_Fscan method results in p_leave
|
||
being called with an appropriate error.
|
||
|
||
|
||
On successful completion the method calls p_1eave (0). The rMaN_RENAME message must therefore be sent
|
||
under the protection of a p_enter.
|
||
|
||
|
||
Further processing of the file rename is handled by the rmscan component.
|
||
|
||
|
||
16 - 6
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
FMAN_MAKE Make a directory tree
|
||
|
||
|
||
INT fman_make(UBYTE *name) ;
|
||
Start the creation of a directory or directory structure as specified by name (using p_mkdir).
|
||
|
||
|
||
The values of fman.dispinfo.protocol and fman.action are both set to rman_maxe. The string pointed to
|
||
by name is copied into the fman.targname buffer and fman.dispinfo.sfname is set to point to this buffer.
|
||
The value of fman.dispinfo. flags Is set to indicate that the appropriate fields are valid.
|
||
|
||
|
||
Following this, the property of the rmmx component is modified directly, setting active.isactive tO TRUE,
|
||
and active.stat to zero. The I/O semaphore is then signalled (by calling p_iosigna1) so that rumx will,
|
||
at some future time, receive an ao_RUN message.
|
||
|
||
|
||
The method returns zero.
|
||
|
||
|
||
See the rmx class for details of further processing.
|
||
|
||
|
||
FMAN_REMOVE Delete a directory structure
|
||
|
||
|
||
INT fman_remove (UBYTE *name) ;
|
||
|
||
|
||
Remove the directory structure specified by the name of a directory pointed to by name. The specified
|
||
directory and all included files and subdirectories are deleted.
|
||
|
||
|
||
The values of fman.dispinfo.protocol and fman.action are both set to rman_remove. The value of
|
||
fman.dispinfo. flags is set to indicate that the appropriate field is valid.
|
||
|
||
|
||
The passed name is parsed into the fman.wildsrcname buffer and adjusted, if necessary (with the aid of a
|
||
call to p_chdir) to ensure that it contains a valid directory name for the relevant filing system. (For
|
||
MSDOS, for example, it ensures that the directory name includes a trailing '\' character.) This may fail if
|
||
the supplied text does not produce a valid directory name.
|
||
|
||
|
||
The rmscan component has fmscan.match Set to point to the string "*" (to match all files) and
|
||
|
||
fmscan. flags Set tO FS_ALL_FILES|FS_INCLUDE_SUBDIRECTORIES |FS_HIDDEN|FS_SYSTEM So that it will
|
||
generate the names of all the files and directories below the specified directory. Following this, the rmscan
|
||
component is sent an rs_Fscan message. The initial start up file name passed with this message is the full
|
||
contents of fman.wildsrcname.
|
||
|
||
|
||
Returns zero if the remove has been started successfully, or calls p_leave on error.
|
||
|
||
|
||
Further processing of the directory removal is handled by the rmscan component.
|
||
|
||
|
||
FMAN_COPYDEV Copy a device
|
||
|
||
|
||
VOID fman_copydev(UBYTE *src, UBYTE *targ, INT flags);
|
||
|
||
|
||
Initiate the copy of the device specified by src to the device and directory name specified by targ,
|
||
reproducing the source device structure under the target directory. This method effectively provides a
|
||
backup service. The results will be unpredictable if src does not point to a device name.
|
||
|
||
|
||
The value of f1ags should be either zero, to copy all files, or rs_MopDIFIED, to restrict the copy to only
|
||
those files which are marked as modified.
|
||
|
||
|
||
The values of fman.dispinfo.protocol and fman. action are both set to rMAN_coPyYING, and
|
||
fman.dispinfo.blksiz iS set to FMAN_READ_S1ZE. The value of fman.dispinfo. flags iS set to indicate
|
||
that the appropriate fields are valid.
|
||
|
||
|
||
The target name is copied into fman.wildtargname, and is converted to a directory name, as in the
|
||
fman_remove method. The source name is parsed into fman.wildsrcname and both names are validated, as
|
||
for the fman_copy method. A further check ensures that the source and target names do not specify the
|
||
same device.
|
||
|
||
|
||
The value of fman.mode 1s Set to P_FREPACE | P_FSTREAM, SO any previously existing target files will be
|
||
overwritten without notification.
|
||
|
||
|
||
The rmscan component has fscan. flags Set to the passed flags value, ored with
|
||
FS_ALL_FILES|FS_INCLUDE_SUBDIRECTORIES|FS_HIDDEN|FS_SYSTEM, and fscan.match Is Set to point to
|
||
the string "*". An rs_Fscan message Is then sent to the rmscan component to generate the list of files to
|
||
copy. The initial start up file name passed with this message is the full contents of fman.wildsrcname.
|
||
|
||
|
||
Any error encountered during the name validation or in rmscan's Fs_Fscan method results in p_leave
|
||
being called with an appropriate error.
|
||
|
||
|
||
16-7
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
On successful completion, the method calls p_1eave (0). The rman_copypEv message must, therefore, be
|
||
sent under the protection of a p_enter.
|
||
|
||
|
||
Further processing of the device copy is handled by the rmscan component.
|
||
|
||
|
||
FMAN_FORMAT Format a device
|
||
|
||
|
||
INT fman_format (UBYTE *devname, UBYTE *volname, UINT flags);
|
||
Initiate the formatting of the device specified by devname, giving it a volume name specified by volname.
|
||
|
||
|
||
Although there is no intrinsic restriction on the filing system in which the format is to take place, the
|
||
REM:: filing system currently does not support the required formatting services. Thus, an error condition
|
||
will occur if an attempt is made to format a device on the REM:: filing system.
|
||
|
||
|
||
The value of flags must be either zero or p_rFLowDENstITv. It specifies the format mode for the formatting
|
||
of floppy disks. (This is primarily supplied to support future expansion since, at the time of writing, there
|
||
is no LOC:: floppy disk drive.)
|
||
|
||
|
||
The passed device name and volume name concatenated into fman.targname and the device is opened for
|
||
formatting with the open file handle written directly to the active.pcb property of the rmrmT component.
|
||
|
||
|
||
The values of fman.dispinfo.protocol and fman.action are both set to FMAN_FORMAT,
|
||
fman.dispinfo.sfname is set to point to the fman.targname buffer and fman.dispinfo.blksiz Is set to 1.
|
||
The value of fman.dispinfo. flags Is set to indicate that the appropriate fields are valid.
|
||
|
||
|
||
The property of the rurmt component is further modified, by setting fmfmt . flags to FMFMT_NaME (defined
|
||
by the rmrmt class) active.isactive to TRUE and active.stat to zero. The I/O semaphore is signalled by
|
||
a call to p_iosignal, ensuring that rmrut will eventually receive an ao_RUN message.
|
||
|
||
|
||
Returns zero if the remove has been started successfully, or calls p_leave on error.
|
||
|
||
|
||
See the rmrmt class for details of further processing.
|
||
|
||
|
||
FMAN_NAME Name a device
|
||
|
||
|
||
INT fman_name(UBYTE *devname, UBYTE *volname) ;
|
||
Change the volume name on the device specified by devname to the name pointed to by voiname.
|
||
|
||
|
||
This method is exceptional, in that the action is performed synchronously. It will always have completed
|
||
(either successfully or with an error) by the time the method terminates.
|
||
|
||
|
||
The method returns zero if the device was named successfully, or calls p_1eave with the appropriate error
|
||
number on failure.
|
||
|
||
|
||
FMAN_INFO Obsolete method
|
||
|
||
|
||
VOID fman_info (VOID) ;
|
||
|
||
|
||
This method is no longer in use and is maintained solely to preserve the OLIB user interface.
|
||
|
||
|
||
FMAN_ATTRIB Set file attributes
|
||
|
||
|
||
VOID fman_attrib(UBYTE *pname, UWORD attribs, UINT flags);
|
||
|
||
|
||
Initiate the setting of the file attributes specified by att ribs for the set of files specified by the wildcarded
|
||
name pointed to by pname.
|
||
|
||
|
||
The value of attribs may take any combination of the following flags:
|
||
|
||
|
||
P_FAWRITE a writable file (not read only, deletable)
|
||
P_FAHIDDEN a hidden file
|
||
|
||
P_FASYSTEM a system file
|
||
|
||
P_FAMOD the file is marked as modified.
|
||
|
||
|
||
Both the set and the clear states of all flags are significant; the clear state has the opposite meaning to the
|
||
set state. For example, if the p_rawr1te flag is not set then the file will be made read only.
|
||
|
||
|
||
16-8
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
The value of f1ags must be either nuLt to restrict the operation to the single specified directory, or
|
||
FS_INCLUDE_SUBDIRECTORIES to extend the setting of attributes to files within all subdirectories of the
|
||
specified directory.
|
||
|
||
|
||
The values of fman.dispinfo.protocol and fman.action are both set to rMAN_ATTRIB and
|
||
fman.dispinfo. flags is set to indicate that the appropriate field is valid.
|
||
|
||
|
||
The name pointed to by pname must not be a null string. Provided it passes this check, it is parsed (with a
|
||
related name of "*") into £man.wildsrcname, and fman.mode is Set to the value of attribs.
|
||
|
||
|
||
The rmscan component has fscan. flags Set to the passed flags value, ored with
|
||
FS_ALL_FILES|FS_HIDDEN|FS_SYSTEM, and fscan.match Is Set to point to the name and extension within
|
||
the fman.wildsrcname buffer. An rs_rscan message is then sent to the rmscan component to generate the
|
||
list of files whose attributes are to be changed. The initial start up file name passed with this message is
|
||
the full contents of fman.wildsrcname.
|
||
|
||
|
||
Any error encountered during the name validation or in rmscan's Fs_Fscan method results in p_leave
|
||
being called with an appropriate error.
|
||
|
||
|
||
On successful completion the method calls p_1eave (0). The rMaN_ATTRIB message must therefore be sent
|
||
under the protection of a p_enter.
|
||
|
||
|
||
Further processing of the setting of attributes is handled by the ruscan component.
|
||
|
||
|
||
Deferred FMAN methods
|
||
|
||
|
||
& FMAN_COMPLETE Processing completed
|
||
|
||
|
||
VOID fman_complete (VOID) ;
|
||
Notify that an asynchronous file manager request has now completed.
|
||
|
||
|
||
This message will not be received if the request failed to start (if, for example, the fman_copy method
|
||
called p_leave with a non-zero parameter). Provided the request started successfully, this message is
|
||
guaranteed to be received, regardless of the reason for the completion. Such reasons include:
|
||
|
||
|
||
e there are no more files to handle
|
||
e the request was aborted by the user, or otherwise cancelled
|
||
e the request terminated with a non-recoverable error
|
||
|
||
|
||
Errors in the file manager request are handled (for example, via the FMAN_ERROR and FMAN_FILEEXIST
|
||
messages) prior to receipt of this message and so the fman_complete method does not need an associated
|
||
completion status.
|
||
|
||
|
||
Note that it is not considered an error if the requested action does not actually process any files, such as in
|
||
a request to delete files from an empty directory. If such a condition needs to be reported, it may be
|
||
detected by the receipt of an FMAN_COMPLETE message that is not preceded by one or more FMAN_NEWNAME
|
||
messages.
|
||
|
||
|
||
Typically, a subclass would use the receipt of this message to destroy any objects associated with the
|
||
display of status information for the current operation and to allow further file management actions be
|
||
selected.
|
||
|
||
|
||
This method is expected to return. Any code that may result in p_leave being called must be run under
|
||
the protection of p_enter.
|
||
|
||
|
||
16-9
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
& FMAN_NEWNAME Processing a new file
|
||
|
||
|
||
VOID fman_newname(FCOPY_DISP *pinfo);
|
||
Notify that processing is about to commence on a new file.
|
||
|
||
|
||
Information about the file is contained in the rcopy_pisp struct pointed to by pinfo. This struct is
|
||
declared in the rcasy class, since it contains data that is used by a number of rcasy subclasses. For
|
||
convenience it is reproduced here:
|
||
|
||
|
||
typedef struct
|
||
{
|
||
|
||
|
||
UWORD flags; Which fields are valid
|
||
|
||
UWORD protocol; Which protocol being used
|
||
|
||
UWORD blksiz; Size of each block
|
||
|
||
UWORD blkno; Current block number
|
||
|
||
UWORD sftype; Source file type
|
||
|
||
UWORD rftype; Receive file type
|
||
|
||
ULONG sfsize; Source file size
|
||
|
||
ULONG rfsize; Receive file size
|
||
|
||
ULONG sfdate; Source file last modification date
|
||
ULONG rfdate; Receive file last modification date
|
||
UBYTE *sfname; Source file name
|
||
|
||
UBYTE *rfname; Receive file name
|
||
|
||
|
||
} FCOPY_DISP;
|
||
|
||
|
||
Since, in general, not all fields contain valid information, the f1ags field indicates which of the fields are
|
||
valid as follows:
|
||
|
||
|
||
FCOPY_DISP_SFTYPE sftype contains either p_FTEXT Or P_FSTREAM
|
||
|
||
FCOPY_DISP_SFSIZE sfsize contains the source file size, in bytes
|
||
|
||
FCOPY_DISP_SFDATE sfdate contains, as a system time, the last modification date of the source file
|
||
|
||
FCOPY_DISP_SFNAME sfname contains a pointer to the source file name as a zero terminated string
|
||
|
||
FCOPY_DISP_RFTYPE rftype contains either p_FTEXT Or P_FSTREAM
|
||
|
||
FCOPY_DISP_RFSIZE rfsize contains the remote or target file size in bytes
|
||
|
||
FCOPY_DISP_RFDATE rfdate contains, as a system time, the last modification date of the remote or
|
||
target file
|
||
|
||
FCOPY_DISP_RFNAME rfname contains a pointer to the remote or target file name as a zero terminated
|
||
string
|
||
|
||
FCOPY_DISP_BLKSIZ blksiz contains a value that represents the amount of data that has been
|
||
processed when each rMaN_UPDATE message is received
|
||
|
||
FCOPY_DISP_BLKNO blkno contains a value specifying the current block number that is being
|
||
|
||
|
||
processed (provided the appropriate fields are valid, the value of sfsize/blksiz
|
||
equals the maximum value of b1kno that will be reached during the processing)
|
||
|
||
|
||
FCOPY_DISP_PROTOCOL protocol contains a value specifying the current rman action (one of
|
||
FMAN_COPYING, FMAN_DELETE, FMAN_RENAME, FMAN_MAKE, FMAN_REMOVE,
|
||
FMAN_FORMAT, FMAN_NAME Of FMAN_ATTRIB)
|
||
|
||
|
||
Irrespective of the contents of the flags field, the contents should not be read outside the fman_newname
|
||
method.
|
||
|
||
|
||
An FMAN_NEWNAME message is sometimes sent even if an error has prevented one or more fields from being
|
||
set up. It is therefore essential always to check if a field is valid before using its contents.
|
||
|
||
|
||
This method has two principal uses:
|
||
e it provides information about the current stage of processing that may be presented to the user
|
||
|
||
|
||
e it supplies a context for any particular error (for example, if a file is read only, it is known in
|
||
advance that the p_delete service will fail with an E_rFILE_RDONLY error).
|
||
|
||
|
||
This method is expected to return. Any code that may result in p_1leave being called must be run under
|
||
the protection of p_enter.
|
||
|
||
|
||
16 - 10
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
& FMAN_UPDATE Section of processing completed
|
||
VOID fman_update (VOID) ;
|
||
Notify that the next section of the requested action has completed.
|
||
|
||
|
||
The message will only be received during the processing of the copy and format services, each time that
|
||
either a block of rmaN_READ_S1zE bytes has been copied, or that a section of the pack has been formatted.
|
||
|
||
|
||
This method may be used to update any progress report that is being presented to the user. The values of
|
||
fman.dispinfo.sfsize and fman.dispinfo.blksiz can be used to determine the number of times that an
|
||
FMAN_UPDATE message will be received, in order to report a percentage completion to the user. Note that
|
||
when formatting (that is, when fman.dispinfo.protocol has the value rmMan_rormat) only the low 16 bits
|
||
of fman.dispinfo.sfsize contain valid data, so in this case the top 16 bits should be masked off.
|
||
|
||
|
||
This method is expected to return. Any code that may result in p_leave being called must be run under
|
||
the protection of p_enter.
|
||
|
||
|
||
& FMAN_FILEEXIST File exists
|
||
|
||
|
||
INT fman_fileexist (VOID);
|
||
Notify that the destination file of a copy exists.
|
||
|
||
|
||
This message will only be received only if fman.mode is not set to cause existing files to be replaced. It can
|
||
therefore only be received if files are being copied as a result of an rMaN_copy message (and not
|
||
FMAN_COPYDEV) Since the fman_copydev method sets fman.mode to include the p_rREPLAcE flag.
|
||
|
||
|
||
The method is expected to return one of the following values:
|
||
-1 (or any other negative value) abandon the copy service
|
||
0 replace this file only, further clashing names will cause this message to be received again
|
||
1 __ skip this file and continues with the next file
|
||
2 replace this file and all subsequent files, regardless of whether the destination file exists.
|
||
|
||
|
||
This method is expected to return. Any code that may result in p_1eave being called must be run under
|
||
the protection of p_enter.
|
||
|
||
|
||
& FMAN_ERROR Determine error response
|
||
INT fman_error(INT errnum) ;
|
||
Determine the action to be taken in response to a detected error with error number errnum.
|
||
|
||
|
||
The method should return a value which specifies the form of error recovery. The range of options is
|
||
different, depending on whether or not the current operation is a file copy (gman. action is
|
||
FMAN_COPYING).
|
||
|
||
|
||
During a file copy the return value may be one of:
|
||
0 abandon copying the current file and continue with the following file
|
||
1 (or any non-zero value) abandon the entire copy operation.
|
||
During any other operation the return value may be one of:
|
||
0 retry the operation on the current file
|
||
1 abandon the entire operation
|
||
2 abandon the operation on the current file and continue with the following file.
|
||
|
||
|
||
This method is expected to return. Any code that may result in p_1leave being called must be run under
|
||
the protection of p_enter.
|
||
|
||
|
||
16-11
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
FMMK
|
||
|
||
|
||
ACTIVE FACTIVE FMMK
|
||
|
||
|
||
gq owner
|
||
|
||
|
||
priority
|
||
|
||
|
||
isactive
|
||
pcb
|
||
stat
|
||
|
||
|
||
destroy fa_close ao_run
|
||
ao_init
|
||
ao_cancel
|
||
ao_abrun
|
||
|
||
ao_queue
|
||
|
||
See
|
||
|
||
|
||
The rmx class is designed to be used as a component of rman which uses it to implement the make
|
||
directory service.
|
||
|
||
|
||
Since the supplied ao_run method contains assumptions about the property of the object whose handle is
|
||
stored in factive.owner, it is not suitable for use other than as a component of rman.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fmmk factive
|
||
|
||
The 'Create directory' active object
|
||
{
|
||
REPLACE ao_run
|
||
|
||
|
||
}
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
FMMK methods
|
||
|
||
|
||
AO_RUN Process a make directory request
|
||
INT ao_run(VOID) ;
|
||
|
||
Make the directory that was specified by an earlier rmMaN_MAKE message.
|
||
|
||
Sends the owning FMAN an FMAN_NEWNAME Message, passing the address of rman's fman.dispinfo struct.
|
||
|
||
|
||
Then makes the directory (and any necessary intermediate directories) with a call to p_mkdir. If this call
|
||
returns an error, FMAN is sent an FMAN_ERROR message and, if this message returns FaLsz, a further attempt
|
||
is made to create the directory. This is repeated until either the directory creation succeeds or the
|
||
FMAN_ERROR message returns a non-zero value.
|
||
|
||
|
||
Following this, rman is sent an FMAN_COMPLETE message to indicate that the processing is complete. Note
|
||
that the ac_run method is executed only once for each rman_MaAKE message.
|
||
|
||
|
||
The method returns RUN_ACTIVE_USED.
|
||
|
||
|
||
16 - 12
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
FMFMT
|
||
|
||
|
||
ACTIVE FACTIVE
|
||
q
|
||
|
||
|
||
owner rdword
|
||
priority rdlen
|
||
isactive flags
|
||
pcb
|
||
stat
|
||
|
||
|
||
destroy fa_close ao_run
|
||
aorinit ao_init ao_abrun
|
||
aereanecet | ao_cancel
|
||
|
||
|
||
ao_queue
|
||
aeTFuAn
|
||
|
||
|
||
The rurnr class is designed to be used as a component of rman, which uses it to implement the format
|
||
service.
|
||
|
||
|
||
Since the supplied methods contain assumptions that the object whose handle is stored in fact ive.owner
|
||
is an instance of the rman class, it is not suitable for use in other situations.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fmfmt factive
|
||
Format active object
|
||
{
|
||
REPLACE ao_run
|
||
REPLACE ao_abrun
|
||
CONSTANTS
|
||
{
|
||
FMFMT_NAME 0x01
|
||
}
|
||
PROPERTY
|
||
{
|
||
UWORD rdword;
|
||
UWORD rdlen;
|
||
|
||
|
||
UWORD flags; Controlling flags
|
||
}
|
||
}
|
||
Property
|
||
fmfmt .rdword a scratch buffer to receive data read during the format process.
|
||
fmfmt .rdlen the number (two!) of bytes read into tmfmt .rdword
|
||
fmfmt .flags controlling flag, initially set to rmmx_Nname and cleared on the first pass
|
||
|
||
|
||
through the ao_run method
|
||
|
||
|
||
FMFMT methods
|
||
|
||
|
||
AO_RUN Process a format request
|
||
|
||
|
||
INT ao_run(VOID);
|
||
Perform a segment of the processing of a file manager format request.
|
||
|
||
|
||
If this is the first time that the method has been called following a rman_rormat message, the first read is
|
||
made, to obtain the format count, and the result is written to the bottom 16 bits of rman's
|
||
fman.dispinfo.sfsize. Following this, rman is sent an FMAN_NEWNAME message, passing the address of
|
||
FMAN'S fman.dispinfo struct.
|
||
|
||
|
||
16 - 13
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
On subsequent calls, unless an error condition is encountered, rman is sent an FMAN_UPDATE Message,
|
||
active.stat is set to TRUE and another read is queued.
|
||
|
||
|
||
If a read request completed with an &_FILE_koF error, indicating that the format is complete, the method
|
||
sends itself an ra_cLOsE message and then sends rMaN an FMAN_COMPLETE Message.
|
||
|
||
|
||
All other errors result in p_1eave being called.
|
||
|
||
|
||
The method returns RUN_ACTIVE_USED.
|
||
|
||
|
||
AO_ABRUN Process formatting error
|
||
VOID ao_abrun (VOID) ;
|
||
Process an error which caused the ao_run method to call p_ieave.
|
||
|
||
|
||
Supersends an AO_ABRUN message and then sends rman an FMAN_COMPLETE message.
|
||
|
||
|
||
FMSCAN
|
||
|
||
|
||
ACTIVE FACTIVE FSCAN FMSCAN
|
||
q
|
||
|
||
|
||
owner
|
||
priority
|
||
|
||
isactive
|
||
|
||
pcb
|
||
|
||
stat
|
||
|
||
|
||
destroy fa—etese fs_matchname ao_abrun
|
||
|
||
|
||
ao_init fs_fscan fs_filename
|
||
|
||
|
||
ao_cancel ao_queue fs_dirname
|
||
|
||
|
||
aorebeun ao_run fs_end_dirlist
|
||
|
||
|
||
fa_close fs_fscan_end
|
||
|
||
|
||
The rmscan class is designed to be used as a component of rman, which uses it to implement the copy file,
|
||
delete file, rename file, remove directory and copy device services.
|
||
|
||
|
||
Since the supplied methods contain assumptions that the object whose handle is stored in fact ive.owner
|
||
is an instance of the rman class, it is not suitable for use in other situations.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fmscan fscan
|
||
|
||
File system scan active object
|
||
{
|
||
REPLACE ao_abrun
|
||
REPLACE fs_filename
|
||
REPLACE fs_dirname
|
||
REPLACE fs_end_dirlist
|
||
REPLACE fs_fscan_end
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
16 - 14
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
FMSCAN methods
|
||
|
||
|
||
AO_ABRUN Process an error
|
||
|
||
|
||
VOID ao_abrun (VOID);
|
||
Handle any error that arises within the ao_run method (provided by rscan).
|
||
|
||
|
||
Reads the owning rman's property and, if man. action iS FMAN_COPYING, sends Ao_CANCEL messages to the
|
||
fman.srcfile and fman.targfile component objects.
|
||
|
||
|
||
Then supersends the ao_aprun message and sends rMaAN an FMAN_COMPLETE message.
|
||
|
||
|
||
FS_ FILENAME Next file name
|
||
|
||
|
||
VOID fs_filename (VOID) ;
|
||
|
||
|
||
Process a new file name during a file name scan (the full file specification of the file is in the fscan.name
|
||
buffer). This method will be called during a copy file, copy device, delete file, delete directory, rename file
|
||
or set attribute service.
|
||
|
||
|
||
Reads the owning rmwan's property and performs one of the following actions, depending on the value of
|
||
|
||
|
||
fman.action:
|
||
|
||
|
||
FMAN_COPYING the name for the copy file is generated by merging the current file name
|
||
from the scan with the wildcarded target name (from fman.wildtargname).
|
||
If this is successful, the source and target files are opened by sending
|
||
FC_OPEN messages to Fan's FMsRc and rmTarG components. The source file
|
||
is opened in read only mode (with the p_rsuare flag set) and the target file
|
||
in text (P_FSTREAM_TEXT) or binary mode, according to the source file type
|
||
specified by fman.mode.
|
||
|
||
|
||
Regardless of the success or failure of the name generation or the attempt to
|
||
open the files, rman is sent an FMAN_NEWNAME message, passing the address of
|
||
the fman.dispinfo struct (whose sfname and rfname elements point
|
||
respectively to the source and target file names). This allows the user
|
||
interface to display names that cause an error in addition to displaying valid
|
||
names.
|
||
|
||
|
||
The copy is started by sending an ao_QuEUE message to FMAN'S FMSRC
|
||
component. Further processing is controlled by the rmsrc and rMTaRG
|
||
components.
|
||
|
||
|
||
FMAN_RENAME the file's new name is generated by merging the current file name from the
|
||
scan and the wildcarded target name (from fman.wildtargname) and FMAN is
|
||
sent an FMAN_NEWNAME message, passing the address of the fman.dispinfo
|
||
struct (whose sfname and rfname elements point respectively to the old and
|
||
new file names). Provided the name generation did not fail, the file is
|
||
renamed.
|
||
|
||
|
||
FMAN_ATTRIB sends FMAN an FMAN_NEWNAME message and sets the file's attributes according
|
||
to the value of fman.mode.
|
||
|
||
|
||
FMAN_DELETE or sends FMAN an FMAN_NEWNAME message and deletes the file.
|
||
FMAN_REMOVE
|
||
|
||
|
||
An £_FILE_EXxIsT error that occurs when trying to create the target file for a copy causes rman to be sent
|
||
an FMAN_FILEEXIST message. See the earlier description of this method for the range of possible return
|
||
values and the resulting actions.
|
||
|
||
|
||
All other errors cause an FMAN_ERROR message to be sent to rman and the return value determines what
|
||
form of error recovery action is taken. The range of possible actions depends on the service that is being
|
||
processed. The various options are listed in the description of the fman_error method.
|
||
|
||
|
||
Except when either copying files or, following an error, the user selects to abandon the entire operation,
|
||
the scan is continued by sending rscan an Ao_QUEUE.
|
||
|
||
|
||
16 - 15
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
FS _DIRNAME Next directory name
|
||
|
||
|
||
VOID fs_dirname (VOID) ;
|
||
|
||
|
||
Process a new directory file during a file name scan. This method will be called when scanning into a
|
||
subdirectory during a copy or delete service.
|
||
|
||
|
||
Reads the owning Fan's property and, if fman. action 1S FMAN_COPYING, adjusts the contents of the
|
||
fman.wildtargname buffer to refer to the new subdirectory. Any error here results in p_leave being
|
||
called.
|
||
|
||
|
||
Sends itself an Aao_QUEUE message to continue the scan.
|
||
|
||
|
||
FS _END_DIRLIST End of subdirectory
|
||
|
||
|
||
VOID fs_end_dirlist (VOID);
|
||
Process the reaching of the end of a subdirectory during a file name scan.
|
||
|
||
|
||
Reads the owning rvan's property and, if fman.action 18 FMAN_REMOVE, deletes the subdirectory whose
|
||
name is specified in the fman.name buffer (any files contained in the subdirectory have been deleted earlier
|
||
in the scan). Any error causes rman to be sent an FMAN_ERROR message. The return value determines the
|
||
action as follows:
|
||
|
||
|
||
0 retry the deletion until it succeeds, or the user decides to skip or abandon
|
||
|
||
|
||
1 abandon the entire operation - send rmscan an AO_CANCEL message and FMAN an FMAN_COMPLETE
|
||
message
|
||
|
||
|
||
2 continue, without deleting the subdirectory.
|
||
|
||
|
||
Otherwise, if man. action 1S FMAN_COPYING, adjusts the contents of the fman.wildtargname buffer to refer
|
||
to the parent directory. Any error here results in p_leave being called.
|
||
|
||
|
||
Sends itself an ao_quEUE message to continue the scan except following a user decision to abort.
|
||
|
||
|
||
FS FSCAN_END Scan completion
|
||
|
||
|
||
VOID fs_fscan_end(VOID);
|
||
Process the end of the file name scan.
|
||
|
||
|
||
Reads the owning rman's property and, if man. action is FMAN_REMOVE, deletes the directory whose name
|
||
is specified in the fman.name buffer (any files and subdirectories have been deleted during the scan). If
|
||
fman.name specifies the root directory, the attempt to delete it will, of course, fail but this is not considered
|
||
an error. Any other error causes rman to be sent an FMAN_ERROR message. The return value determines the
|
||
action as follows:
|
||
|
||
|
||
0 retry the deletion until it succeeds, or the user decides to skip or abandon
|
||
|
||
|
||
1 abort the entire operation - send rMscan an AO_CANCEL message and send rMaN an FMAN_COMPLETE
|
||
message
|
||
|
||
|
||
2 continue, without deleting the directory.
|
||
|
||
|
||
Sends rvan an FMAN_COMPLETE message.
|
||
|
||
|
||
16 - 16
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
FMSRC
|
||
|
||
|
||
ACTIVE FACTIVE FCASY
|
||
q
|
||
|
||
|
||
owner recvname
|
||
priority flags
|
||
isactive
|
||
|
||
pcb
|
||
|
||
stat
|
||
|
||
|
||
destroy #a—ctese ao_cancel fc_request_comp
|
||
|
||
|
||
ao_init ao_run
|
||
|
||
|
||
2 + ao_queue
|
||
ao_abrun fa_close
|
||
fc_write
|
||
|
||
|
||
fc_open
|
||
|
||
|
||
The rsrc class is designed to be used as a component of rman which uses it to implement the reading of
|
||
the source file in the copy file service.
|
||
|
||
|
||
Since the supplied method contains assumptions that the object whose handle is stored in fact ive.owner
|
||
is an instance of the rman class, it is not suitable for use in other situations.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fmsrc fcasy
|
||
Source file active object
|
||
|
||
|
||
{
|
||
REPLACE fc_request_comp
|
||
|
||
|
||
}
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
FMSRC methods
|
||
|
||
|
||
FC_REQUEST COMP Process a read completion
|
||
|
||
|
||
VOID fc_request_comp (VOID) ;
|
||
Process the completion of a read from the source file.
|
||
|
||
|
||
The read will always have been of rman_READ_S1zE bytes into rman's fman.buf buffer. On completion of
|
||
the read fman.srcien contains the number of bytes actually read.
|
||
|
||
|
||
If the read completed successfully, it sends an rc_wRITE message to FMAN's FMTARG component to write
|
||
fman.srclen bytes from fman.buf to the destination file.
|
||
|
||
|
||
If the read completed with an z_F1Lz_k£oF error, the copy of the file is complete. rman's FMTARG component
|
||
is sent an FA_CLOSE message, the destination file is set to have the attributes and modification date of the
|
||
source file (an error in reading the attributes of the source file causes p_leave to be called). If the copy is
|
||
of modified files only, the modified (p_ramop) attribute of the source file is cleared. An ao_QUEUE message
|
||
is sent to FMAN's FSCAN component to continue the scan for another file to copy.
|
||
|
||
|
||
If the read completed with any other error, rman's FMTARG Component is sent an Ao_CANCEL message and
|
||
FMAN is Sent an FMAN_ERROR Message, which allows the user to skip this file and continue, or abort the copy
|
||
service.
|
||
|
||
|
||
16-17
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
FMTARG
|
||
|
||
|
||
ACTIVE FACTIVE FCASY FMTARG
|
||
q
|
||
|
||
|
||
owner recvname
|
||
priority flags
|
||
isactive
|
||
|
||
pcb
|
||
|
||
stat
|
||
|
||
|
||
destroy #a—ctese ao_cancel fc_request_comp
|
||
|
||
|
||
ao_init ao_run
|
||
|
||
|
||
ae-ean ao_queue
|
||
ao_abrun fa_close
|
||
fc_write
|
||
|
||
|
||
fc_open
|
||
|
||
|
||
The rmtare class is designed to be used as a component of rman, which uses it to implement the writing of
|
||
the target file in the copy file service.
|
||
|
||
|
||
Since the supplied method contains assumptions that the object whose handle is stored in fact ive.owner
|
||
is an instance of the rman class, it is not suitable for use in other situations.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file factive.cl (generated header file factive.g).
|
||
|
||
|
||
CLASS fmtarg fcasy
|
||
Target file active object
|
||
|
||
{
|
||
|
||
REPLACE fc_request_comp
|
||
|
||
|
||
}
|
||
Property
|
||
|
||
|
||
None.
|
||
|
||
|
||
FMTARG methods
|
||
|
||
|
||
FC_REQUEST COMP Process a write completion
|
||
|
||
|
||
VOID fc_request_comp (VOID);
|
||
Process the completion of a write to the target file.
|
||
|
||
|
||
If the write completed successfully, sends rman an FMAN_UPDATE message, updates the value of rman's
|
||
fman.srclen tO FMAN_READ_SIZE and sends an Ao_QUEUE message to FMAN'S FMSRC Component.
|
||
|
||
|
||
If the write completed with an error, rmMan's FMSRC Component is sent an AO_CANCEL message and FMaN is
|
||
sent an FMAN_ERROR message, which allows the user to skip this file and continue or abandon the copy
|
||
service.
|
||
|
||
|
||
16 - 18
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
File manager example
|
||
|
||
|
||
The following example is of a simple application to back up the contents of M-:, using a console window as
|
||
the user interface. It formats an SSD in B: and copies the entire contents of M: to B:. The process may be
|
||
|
||
|
||
aborted at any time by pressing the ESC key.
|
||
|
||
|
||
The category file, mcopy.cat, is as follows:
|
||
|
||
|
||
IMAGE mcopy
|
||
EXTERNAL olib
|
||
|
||
|
||
INCLUDE appman.g
|
||
INCLUDE factive.g
|
||
INCLUDE p_keyb.h
|
||
|
||
|
||
CLASS bakfman fman
|
||
|
||
|
||
File manager to perform format and copydev operations
|
||
|
||
|
||
{
|
||
REPLACE fman_complete
|
||
REPLACE fman_newname
|
||
REPLACE fman_update
|
||
REPLACE fman_error
|
||
PROPERTY
|
||
{
|
||
UWORD count;
|
||
UWORD increment;
|
||
UWORD maxcount;
|
||
}
|
||
}
|
||
|
||
|
||
CLASS breakkey active
|
||
Looks for Esc key being pressed
|
||
{
|
||
REPLACE ao_init
|
||
REPLACE ao_run
|
||
REPLACE ao_queue
|
||
PROPERTY
|
||
{
|
||
P_CON_KBREC k;
|
||
}
|
||
|
||
|
||
CLASS bakapp appman
|
||
|
||
{
|
||
|
||
REPLACE am_init
|
||
|
||
PROPERTY 2
|
||
{
|
||
PR_BAKFMAN *fman;
|
||
PR_BREAKKEY *breakkey;
|
||
}
|
||
|
||
}
|
||
|
||
|
||
Operation now complete
|
||
|
||
Operation now on this file(s)
|
||
|
||
Update copying display
|
||
|
||
Error in operation, abandon/continue
|
||
|
||
|
||
Note that no method function is supplied for the file manager's deferred fman_fileexist method. It will
|
||
never be called in this example since the only file copies are ones that will replace any existing file of the
|
||
|
||
|
||
Same name.
|
||
|
||
|
||
16 - 19
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
The code for the application is as follows. Note that pressing Esc during the format will leave the SSD in
|
||
B: unformatted.
|
||
|
||
|
||
#include <p_std.h>
|
||
#include <p_gen.h>
|
||
#include <p_file.h>
|
||
#include <p_sys.h>
|
||
#include <p_keyb.h>
|
||
#include <epoc.h>
|
||
|
||
#include <mcopy.g>
|
||
|
||
|
||
GLREF_D PR_BAKAPP *w_am;
|
||
GLREF_D VOID *winHandle; /* console device handle */
|
||
|
||
|
||
LOCAL_D INT escaped;
|
||
#pragma save,METHOD_CALL
|
||
|
||
|
||
METHOD VOID breakkey_ao_init (PR_BREAKKEY *self)
|
||
{
|
||
self—>active.priority=PRIORITY_ACTIVE_WSERV;
|
||
self->active.pcb=winHandle; /* console device must already be open */
|
||
p_send3 (w_am, O_AM_ADD_TASK, self) ;
|
||
p_send2 (self, O_AO_QUEUE) ;
|
||
}
|
||
|
||
|
||
METHOD VOID breakkey_ao_queue (PR_BREAKKEY *self)
|
||
|
||
/*
|
||
|
||
Checks for ESC during file manager commands
|
||
|
||
*/
|
||
{
|
||
p_ioc4 (self-—>active.pcb, P_FREAD, &self->active.stat, &self-—>breakkey.k) ;
|
||
self—>active.isactive=TRUE;
|
||
|
||
|
||
}
|
||
|
||
|
||
METHOD breakkey_ao_run(PR_BREAKKEY *self)
|
||
|
||
|
||
/*
|
||
Aborts if ESC pressed
|
||
baw A
|
||
{
|
||
if (self->breakkey.k.keycode!=0x1b)
|
||
p_send2 (self, O_AO_QUEUE) ;
|
||
else
|
||
{
|
||
escaped=TRUE;
|
||
p_printf("\r\nUser aborted") ;
|
||
p_send2 (w_am->bakapp.fman,O_FMAN_CANCEL); /* stops any service cleanly at any
|
||
time */
|
||
|
||
|
||
}
|
||
return (RUN_ACTIVE_USED) ;
|
||
}
|
||
|
||
|
||
METHOD bakfman_fman_error(PR_BAKFMAN *self,INT error)
|
||
/*
|
||
An error was detected in the operation of the engine.
|
||
This method causes the operation to be abandoned and,
|
||
in this example, results in the application being
|
||
terminated.
|
||
*/
|
||
|
||
{
|
||
|
||
escaped=TRUE;
|
||
|
||
return (1);
|
||
|
||
|
||
}
|
||
|
||
|
||
16 - 20
|
||
|
||
|
||
16 FILE MANAGEMENT CLASSES
|
||
|
||
|
||
METHOD VOID bakfman_fman_complete (PR_BAKFMAN *self)
|
||
/*
|
||
The last requested operation is now complete, for ANY reason.
|
||
xf
|
||
{
|
||
if ((self->fman.action==FMAN_FORMAT) && (!escaped) )
|
||
p_printf("\r\n*** Format successfully completed ***\r\n");
|
||
p_send2 (w_am,O_AM_STOP) ;
|
||
}
|
||
|
||
|
||
#define FORMAT_FLAGS (FCOPY_DISP_BLKS1IZ|FCOPY_DISP_SFSIZE|FCOPY_DISP_SFNAME)
|
||
|
||
|
||
METHOD VOID bakfman_fman_newname (PR_BAKFMAN *self,FCOPY_DISP *pinfo)
|
||
/*
|
||
A new file is being acted on by the engine.
|
||
*/
|
||
{
|
||
if (self->fman.action==FMAN_COPYING)
|
||
{
|
||
if (pinfo->flags&FCOPY_DISP_SFNAME)
|
||
p_printf ("Copying %s",pinfo->sfname) ;
|
||
}
|
||
if (self->fman.action==FMAN_FORMAT)
|
||
{
|
||
/* store some info to avoid accessing it outside this method */
|
||
self-—>bakfman.count=self->bakfman.maxcount=0;
|
||
if ((pinfo->flags&FORMAT_FLAGS) ==FORMAT_FLAGS)
|
||
{
|
||
self—>bakfman.increment=pinfo->blksiz;
|
||
self—>bakfman.maxcount=pinfo->sfsize;
|
||
|
||
|
||
/* copy sfsize into UWORD since, for format, only lower 16 bits are valid */
|
||
|
||
|
||
p_printf ("Formatting %s",pinfo->sfname) ;
|
||
|
||
|
||
}
|
||
|
||
|
||
METHOD VOID bakfman_fman_update (PR_BAKFMAN *self)
|
||
/*
|
||
Update display, as next copy/format block has been processed.
|
||
Does not report progress on the copying of files.
|
||
af
|
||
{
|
||
if (self->fman.action==FMAN_FORMAT && self->bakfman.maxcount)
|
||
{
|
||
self->bakfman.count+=self->bakfman.increment;
|
||
p_print ("\r%05u %05u", self—>bakfman. count, self->bakfman.maxcount) ;
|
||
}
|
||
}
|
||
|
||
|
||
METHOD bakapp_am_init (PR_BAKAPP *self)
|
||
{
|
||
|
||
|
||
p_supersend3 (self,O_AM_INIT,FLG_APPMAN_CLEAN|FLG_APPMAN_ONLYONE) ;
|
||
self—>bakapp.fman=f_newsend (CAT_MCOPY_MCOPY, C_BAKFMAN, O_FMAN_INIT) ;
|
||
self—>bakapp.breakkey=f_newsend (CAT_MCOPY_MCOPY, C_BREAKKEY, O_AO_INIT) ;
|
||
return (0);
|
||
|
||
|
||
}
|
||
|
||
|
||
16 - 21
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
#pragma ENTER_CALL
|
||
|
||
|
||
LOCAL_C INT RunIt (VOID)
|
||
/*
|
||
Runs the format and copy services.
|
||
Designed to run in an enter harness.
|
||
xf,
|
||
{
|
||
f_leave (p_entersend5 (w_am—->bakapp.fman,O_FMAN_FORMAT, "LOC::B:\\", "BACKUP", 0) );
|
||
p_send2 (w_am,O_AM_START) ;
|
||
if (!escaped)
|
||
{
|
||
f_leave (p_entersend5 (w_am—>bakapp. fman, O_FMAN_COPYDEV, "LOC: :M:","LOC::B:",0));
|
||
p_send2 (w_am,O_AM_START) ;
|
||
}
|
||
p_send2 (w_am, O_DESTROY) ;
|
||
return (FALSE) ;
|
||
}
|
||
|
||
|
||
LOCAL_C INT DoIt (VOID)
|
||
/*
|
||
Creates and initialises the application manager.
|
||
Runs the format and copy services under a further enter harness.
|
||
Designed to run in an enter harness to catch initialisation failures.
|
||
*/
|
||
|
||
{
|
||
|
||
INT err;
|
||
|
||
|
||
escaped=FALSE;
|
||
|
||
w_am=(PR_BAKAPP *) f_new(CAT_MCOPY_MCOPY,C_BAKAPP) ;
|
||
p_send2 (w_am,O_AM_INIT);
|
||
|
||
err=p_enterl (RunIt);
|
||
|
||
p_send2 (w_am, O_DESTROY) ;
|
||
|
||
return(err);
|
||
|
||
|
||
}
|
||
|
||
|
||
#pragma restore
|
||
|
||
|
||
GLDEF_C main(VOID)
|
||
|
||
|
||
/*
|
||
Copy all of M: to an SSD in B:
|
||
tf
|
||
|
||
{
|
||
|
||
p_linklib(0);
|
||
|
||
p_printf ("Backing up M: to B:"); /* convenient way to start up the console device
|
||
*/
|
||
|
||
|
||
return (p_enterl (DoIt));
|
||
}
|
||
|
||
|
||
The nested p_enter protection for the calls to port and Runit ensure that the application manager is not
|
||
sent a DEsTRoy message if it fails to be created, but is destroyed in the event of any other failure.
|
||
|
||
|
||
The pEstRoy message is not strictly necessary since the operating system will clean up all resources used
|
||
by an application when the application terminates. Nevertheless, it is good practice to ensure that an
|
||
application is in a fit state to free its resources at any time.
|
||
|
||
|
||
In this case, by use of the auto-destruction mechanism, destroying the application manager will cause the
|
||
destruction of both the file manager and the preakkeEy active object. The superclass active object dest roy
|
||
method ensures that any outstanding console keyboard read is cancelled and that the console device
|
||
(whose handle is stored in active. pcb) is closed.
|
||
|
||
|
||
16 - 22
|
||
|
||
|
||
CHAPTER 17
|
||
|
||
|
||
THE LOCS LOCAL FILE SCAN CLASS
|
||
|
||
|
||
flags
|
||
|
||
|
||
pcb
|
||
|
||
|
||
pname
|
||
match
|
||
info
|
||
name
|
||
|
||
|
||
wildname
|
||
|
||
|
||
1ls_matchname
|
||
|
||
|
||
ls_scan
|
||
|
||
|
||
ls_filename
|
||
|
||
|
||
The tocs abstract class provides a set of methods to perform a synchronous scan of the LOC:: and ROM::
|
||
filing systems to locate file names which match a wildcarded name. It is similar in purpose to, but simpler
|
||
than, the asynchronous scanning classes described in the File Active Objects and File Lists chapters.
|
||
|
||
|
||
LOCS uses a synchronous scan, so once a scan has been started no other events can be processed until the
|
||
scan completes. However, since file system requests on the LOC:: and ROM:: filing systems complete
|
||
very quickly, this is unlikely to cause any significant loss of responsiveness to user input.
|
||
|
||
|
||
Locs must be subclassed to provide the deferred Ls_FILENamME method, to process matching file names.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e the PLIB/EPOC file system directory read functions
|
||
e =the LOC:: and ROM:: filing systems
|
||
|
||
|
||
17-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
The tocs class subclasses root and is defined in the sub-category file factive.cl (with generated header
|
||
file factive.g).
|
||
|
||
|
||
CLASS
|
||
|
||
|
||
locs root
|
||
|
||
|
||
Synchronous Local/ROM filing system file finder
|
||
|
||
|
||
{
|
||
|
||
|
||
ADD 1ls_matchname
|
||
ADD 1ls_scan
|
||
|
||
|
||
DEFER 1s_filename
|
||
|
||
|
||
CONSTANTS
|
||
|
||
|
||
{
|
||
LOCS_FLG_ROM
|
||
LOCS_FLG_LOC
|
||
|
||
|
||
LOCS_FLG_ROOT
|
||
|
||
|
||
Matching name checker
|
||
Start the scan off
|
||
Process located file name
|
||
|
||
|
||
0x1000
|
||
0x2000
|
||
(0x4000 | LOCS_FLG_LOC)
|
||
|
||
|
||
LOCS_FLG_ROOT_ONLY 0x4000 Internal to locs only
|
||
|
||
|
||
}
|
||
|
||
|
||
PROPERTY
|
||
|
||
|
||
}
|
||
|
||
|
||
{
|
||
|
||
UWORD flags;
|
||
UBYTE *pcb;
|
||
UBYTE *pname;
|
||
UBYTE *match;
|
||
P_INFO info;
|
||
|
||
|
||
Controlling flags
|
||
|
||
Open directory file handle
|
||
Where to read names into
|
||
Match name string
|
||
Currently found file info
|
||
|
||
|
||
UBYTE name [P_FNAMESIZE];
|
||
UBYTE wildname [P_FNAMESIZE];
|
||
|
||
|
||
}
|
||
|
||
|
||
Property
|
||
|
||
|
||
LOocs
|
||
|
||
|
||
Locs
|
||
|
||
|
||
Locs
|
||
|
||
|
||
locs.
|
||
|
||
|
||
locs
|
||
|
||
|
||
locs
|
||
|
||
|
||
17-2
|
||
|
||
|
||
Ltocs.
|
||
|
||
|
||
flags
|
||
|
||
|
||
-pcb
|
||
|
||
|
||
-pname
|
||
|
||
|
||
-match
|
||
|
||
|
||
info
|
||
|
||
|
||
-name
|
||
|
||
|
||
.-wildname
|
||
|
||
|
||
controlling flags to drive the scan. This field should not be accessed by
|
||
any subclass.
|
||
|
||
|
||
the currently opened directory file handle. It should not be accessed by
|
||
any subclass.
|
||
|
||
|
||
a pointer to the name and extension within the full file specification in the
|
||
locs.name buffer. A subclass may use this pointer to read the file name.
|
||
|
||
|
||
a pointer to the name and extension within the wildcard full file
|
||
specification in the locs.wildname buffer. Used to determine if a
|
||
generated file name matches the name requirements. A subclass should
|
||
treat this as read only.
|
||
|
||
|
||
the file information corresponding to the file name in 1ocs.name, read
|
||
from the currently opened directory file. A subclass should treat this as
|
||
read only.
|
||
|
||
|
||
the full file specification of the current file, whose file information is in
|
||
locs.info. A subclass should treat this as read only.
|
||
|
||
|
||
contains a parsed version of the wildcarded name passed to the 1s_scan
|
||
method. If necessary, it is modified during the scan in order to search the
|
||
ROM.:: and/or the root directories of the LOC:: filing systems.
|
||
|
||
|
||
17 THE LOCS LOCAL FILE SCAN CLASS
|
||
|
||
|
||
LOCS methods
|
||
JLS SCAN Perform a file scan
|
||
|
||
|
||
VOID 1ls_scan(UBYTE *pname, INT flags);
|
||
|
||
|
||
Perform a synchronous search for files with names matching the wildcard string pointed to by pname and
|
||
of type and location specified by flags. This method will not return until the scan is complete.
|
||
|
||
|
||
The value of flags may be any ored combination of items from the following two groups:
|
||
|
||
|
||
P_FAMOD select only modified files
|
||
|
||
P_FAHIDDEN include hidden files
|
||
|
||
P_FASYSTEM include system files
|
||
|
||
LOCS_FLG_ROM scan the ROM-:: device (scanned first)
|
||
|
||
LOCS_FLG_LOC scan the specified directory of all LOC:: devices (in alphabetical order)
|
||
|
||
LOCS_FLG_ROOT scan the root directory of a LOC:: device before scanning any specified
|
||
directory
|
||
|
||
|
||
The method first copies the value of flags into locs. flags and parses the string pointed to by pname into
|
||
the 1locs.wildname buffer. It then reads file names, from the directory files specified by pname and flags,
|
||
into the 1ocs.name buffer. For each file name it sends an Ls_mMaTCHNAME message. If this returns TRUE it
|
||
also sends an LS_FILENAME message. The sending of this message is under the protection of p_enter so
|
||
that the 1s_scan method itself will never be terminated by a call to p_leave.
|
||
|
||
|
||
The scan is terminated either when there are no more file names to read or when the 1s_ filename method
|
||
returns a non-zero value.
|
||
|
||
|
||
For example:
|
||
p_send4 (locs, O_LS_SCAN, "fon\\*. fon", LOCS_FLG_ROM|LOCS_FLG_ROOT | LOCS_FLG_LOC) ;
|
||
|
||
|
||
will find all fon files in the ROM, and in the root and \fon directories of all SSDs in the LOC:: filing
|
||
system.
|
||
|
||
|
||
J LS MATCHNAME Check file name match
|
||
|
||
|
||
INT 1ls_matchname (VOID) ;
|
||
|
||
|
||
Check the file name pointed to by 1ocs.pname, whose file type information is in locs. info, against the
|
||
wildcarded name pointed to by 1ocs.match and the file types in locs. flags.
|
||
|
||
|
||
This method is not called when the name is of a volume or a directory file.
|
||
|
||
|
||
Returns true if the file matches the specified requirements else FaLsE.
|
||
|
||
|
||
Deferred LOCS methods
|
||
LS FILENAME Process a file name
|
||
|
||
|
||
INT ls_filename(UBYTE *pname) ;
|
||
|
||
|
||
This method should contain the logic to process the name of a file that matches the initial specifications as
|
||
passed to the 1s_scan method.
|
||
|
||
|
||
It is called from the 1s_scan method each time the 1s_matchname method returns TRUE, with pname
|
||
pointing to the full file specification in the 1ocs.name buffer. If the subclass is only interested in the file
|
||
name and extension, it may read this via locs.pname.
|
||
|
||
|
||
The method is expected to return raLsE to continue the scan or, having found a file that satisfies its
|
||
requirements, it may return TRUE to terminate the scan immediately, causing the 1s_scan method to
|
||
return.
|
||
|
||
|
||
If this method does not return TRUE the scan will terminate when the ts_scan method has no more file
|
||
names to read.
|
||
|
||
|
||
17 -3
|
||
|
||
|
||
CHAPTER 18
|
||
|
||
|
||
SYSTEM SERVICES
|
||
|
||
|
||
Each member of the SIBO family of machines supplies one or more of the following global system
|
||
services:
|
||
|
||
|
||
e to allocate or replace an icon position, or to remove an icon
|
||
|
||
e torun a file-based application by specifying the file that it is to open
|
||
e¢ to nominate the current link paste server
|
||
|
||
e to provide the process id of the current link paste server, if any
|
||
|
||
|
||
All these services are available on MC 200/400 machines, where they are provided by the System process,
|
||
SYSS$SHLL.
|
||
|
||
|
||
On Series 3 and HC machines, only the two link paste related services are available and are supplied by
|
||
the window server process, syss$wsRV.
|
||
|
||
|
||
The available services are accessed by means of an inter-process message being sent to the supplying
|
||
process. The system class provides a simplified form of access that hides the inter-process messaging
|
||
mechanism.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
|
||
|
||
e the initialisation of the appman class
|
||
|
||
|
||
SYSTEM
|
||
|
||
|
||
SYSTEM
|
||
|
||
|
||
pid
|
||
|
||
|
||
sy_init
|
||
|
||
|
||
sy_icon_pos
|
||
|
||
|
||
sy_link_server
|
||
sy_link_paste
|
||
|
||
|
||
sy_exec_open
|
||
|
||
|
||
The system class provides simple access to the available system services, as described above.
|
||
|
||
|
||
An application does not normally explicitly create and initialise an instance of the system class. On MC
|
||
and Series 3 machines, an instance of the system class is usually created and initialised automatically by
|
||
passing a flag (FLG_APPMAN_SYSTEM on the MC, or FLG_APPMAN_LINKING on the Series 3) to the application
|
||
manager's aM_In1T method. In this case the handle of the created and initialised system instance is stored
|
||
in the application manager's appman. system property field.
|
||
|
||
|
||
Note that FLG_APPMAN_LINKING (which is defined in hwimman.g) and FLG_APPMAN_SYSTEM cause the
|
||
appropriate process name (syS$SHLL or SYS$wsRvV respectively) to be used by the application manager's
|
||
am_init method.
|
||
|
||
|
||
18-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Class definition
|
||
|
||
|
||
The system class subclasses root and is defined in the sub-category file appman.cl (with generated header
|
||
file appman.g).
|
||
|
||
|
||
CLASS system root
|
||
For access to system services
|
||
|
||
|
||
ADD sy_init Gets the pid of the supplying process
|
||
ADD sy_icon_pos Allocate/remove/replace an icon position
|
||
ADD sy_link_server Nominate oneself as the link paste server
|
||
ADD sy_link_paste Get pid and format mask of link paste server
|
||
ADD sy_exec_open Execute an application to open specified file
|
||
CONSTANTS
|
||
IC_SYSTEM_ALLOC 0) Allocate an icon position
|
||
IC_SYSTEM_REMOVE 1 Remove an icon position
|
||
|
||
|
||
IC_SYSTEM_REPLACE 2 Replace an icon position
|
||
}
|
||
|
||
|
||
PROPERTY
|
||
UWORD pid; Process id of shell
|
||
}
|
||
}
|
||
Property
|
||
system.pid the process id of the System process. This is private to the SYSTEM class
|
||
|
||
|
||
and should not be accessed by any other code
|
||
|
||
|
||
SYSTEM methods
|
||
J SY_INIT Initialise
|
||
|
||
|
||
VOID sy_init (TEXT *sysnam) ;
|
||
|
||
|
||
Initialise, by finding - and storing in system. pia - the process id of the System application whose
|
||
application name is sysnam.
|
||
|
||
|
||
Returns zero if successful. On error, writes nothing to system. pid and returns the relevant error number.
|
||
|
||
|
||
As explained earlier, this method is not normally called explicitly by application code. It is called by the
|
||
application manager in its am_init method which supplies the appropriate text.
|
||
|
||
|
||
SY_ICON_POS Control icon positioning
|
||
|
||
|
||
VOID sy_icon_pos(UINT req, P_POINT *pos, UINT prev);
|
||
This service is only available on MC 200/400 machines.
|
||
Control the positioning of icons representing tasks. The behaviour depends on the value of req, as follows:
|
||
|
||
|
||
IC_SYSTEM_ALLOC Allocate an icon position, writing the allocated position in *pos and
|
||
returning an index corresponding to this position. If prev is -1, the icon is
|
||
allocated at the first free position. Otherwise prev should be an index
|
||
returned by a previous sy_IcoN_Pos message, when an attempt will be made
|
||
to allocate the corresponding position. If this position is occupied, the first
|
||
free position is allocated, as for a prev of -1.
|
||
|
||
|
||
IC_SYSTEM_REMOVE Remove the icon at position *pos, which should contain a position
|
||
previously generated by an sy_sysTEM_Pos message with a req of either
|
||
IC_SYSTEM_ALLOC Of IC_SYSTEM_REPLACE. The value of prev is ignored.
|
||
Returns zero.
|
||
|
||
|
||
IC_SYSTEM_REPLACE Replace the position corresponding to the index value in prev (which should
|
||
be an index returned by a previous sy_1con_Pos message) with the position
|
||
in *pos. The value in *pos is updated to be either the 'snap' position nearest
|
||
to the passed position, or the original position if this nearest position is
|
||
occupied. Returns an index corresponding to the new position.
|
||
|
||
|
||
18 -2
|
||
|
||
|
||
18 SYSTEM SERVICES
|
||
|
||
|
||
SY_LINK_SERVER Set link paste server
|
||
|
||
|
||
INT sy_link_server(ULONG fmask) ;
|
||
Nominate the current process (that is, the process which sends this message) as the link paste server.
|
||
|
||
|
||
The value of fmask is a bit mask of the formats in which the server is prepared to provide data. The
|
||
formats are discussed in the description of the L1nxsv class definition in the Link Paste chapter of this
|
||
manual.
|
||
|
||
|
||
Returns zero.
|
||
|
||
|
||
SY_LINK_PASTE Get link paste server
|
||
|
||
|
||
INT sy_link_paste(ULONG *pfmt) ;
|
||
Find the process id of the application (if any) that is the current link paste server.
|
||
|
||
|
||
If such a process exists, writes the bit mask of available formats to *pfmt and returns the process id. The
|
||
formats are discussed in the description of the L1nxsv class definition in the Link Paste chapter of this
|
||
manual.
|
||
|
||
|
||
If there is no current link paste server, writes nothing to *pfmt and returns zero.
|
||
|
||
|
||
SY_EXEC OPEN Run an application by file name
|
||
INT sy_exec_open(TEXT *pname) ;
|
||
This service is only available on MC 200/400 machines.
|
||
|
||
|
||
Queue a request to run the appropriate application that will open the file whose name is pointed to by
|
||
|
||
|
||
pname.
|
||
|
||
|
||
The application is selected on the basis of the file name extension together with the application/extension
|
||
associations declared in one or more def.ext files.
|
||
|
||
|
||
Returns zero without waiting for the request to complete.
|
||
|
||
|
||
CHAPTER 19
|
||
|
||
|
||
INTER-PROCESS COMMUNICATION
|
||
|
||
|
||
This chapter describes the 1pcs and sERVER classes that may be used to receive and process inter-process
|
||
messages from one or more sources.
|
||
|
||
|
||
A process running under EPOC may open only one message channel for receiving inter-process messages.
|
||
Inter-process messages may, however, arrive from a variety of sources. In order to distinguish between
|
||
messages from different sources, it is conventional to group them, assigning a range of message type
|
||
values to each source. (The type value is stored in the type field of the &_messacz struct that forms the
|
||
header of each inter-process message.)
|
||
|
||
|
||
The following message groups are defined and used by existing software:
|
||
|
||
|
||
CONSOL message types 0 to OxOf (MC 200/400 only)
|
||
TOPLIP message types 0x10 to Ox1f (MC 200/400 only)
|
||
LINKSV message types 0x20 to Ox2f (link paste)
|
||
Automatic test system message types 0x30 to Ox3f
|
||
|
||
|
||
It is usually convenient to use a separate server object (by definition, a subclass of SERVER) to process the
|
||
receipt of inter-process messages of each group. For example, all message types concerned with link paste
|
||
should be handled by a link paste server object.
|
||
|
||
|
||
The rpcs class provides the central mechanism by which a process receives an inter-process message and
|
||
directs it to the appropriate server object. The relationship between 1pcs and server objects is analogous to
|
||
that between appman and active objects.
|
||
|
||
|
||
It may be noted that a process only needs to create an instance of the rpcs class (a message channel) if it
|
||
receives messages; a process may send an inter-process message without opening a message channel.
|
||
|
||
|
||
Precursors
|
||
The reader is assumed to understand:
|
||
e the active class and the application manager's event scheduling mechanisms
|
||
|
||
|
||
e the PLIB inter-process messaging services, described in the Processes and Inter-process
|
||
Messaging chapter of the PLIB Reference manual
|
||
|
||
|
||
e =the p_enter and p_leave error handling services
|
||
|
||
|
||
Inheritance tree
|
||
|
||
|
||
—
|
||
|
||
|
||
fs rec : —
|
||
( active /
|
||
sS )
|
||
U =.
|
||
Pa es
|
||
C Ilpcs /
|
||
“Ss )
|
||
‘ Pat
|
||
cae
|
||
( server /
|
||
~~ {n} )
|
||
ee
|
||
|
||
|
||
19-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
IPCS
|
||
|
||
|
||
ACTIVE
|
||
|
||
|
||
gq
|
||
priority
|
||
isactive
|
||
pcb
|
||
|
||
stat
|
||
|
||
|
||
destroy
|
||
ao_init
|
||
ao_cancel
|
||
ao_queue
|
||
ao_run
|
||
|
||
|
||
ao_abrun
|
||
|
||
|
||
ip_add_server
|
||
|
||
|
||
The recs class is an active object that provides services to receive inter-process messages and dispatch
|
||
them to the appropriate server object.
|
||
|
||
|
||
This class should be used when several servers are required, to process messages of more than one group.
|
||
It should also be used if the application is to support link paste. The application can then take advantage
|
||
of the link paste server (described in the following chapter) even if no other servers are required.
|
||
|
||
|
||
In other cases, where only one group of message types is to be processed, it may be more convenient to
|
||
subclass recs so that the messages are processed in the subclass ao_run method, rather than in a separate
|
||
server.
|
||
|
||
|
||
An instance of the recs class is created and initialised automatically during the application manager's
|
||
am_init method, provided the rLc_appman_1pcs flag is set, and its handle is written to appman.ipcs.
|
||
|
||
|
||
If you subclass rpcs you must explicitly create and initialise the instance yourself. You must not specify
|
||
the rLG_appman_ipcs flag in the am_In1IT message to aPpMaN (attempting to open more than one
|
||
messaging channel will cause the application to fail). You may, however, store the handle in the
|
||
application manager's appman.ipcs So that the object will be destroyed automatically when the application
|
||
manager is destroyed at termination of the application.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file appman.cl (generated header file appman.g).
|
||
|
||
|
||
CLASS ipcs active
|
||
The ipc server active object for inter-process communication
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE destroy Set pcb to NULL as not really handle based
|
||
REPLACE ao_init Init message queue, add to appman queue, read
|
||
REPLACE ao_cancel Cancel a queued message read
|
||
REPLACE ao_queue Queue a message read
|
||
REPLACE ao_run Despatch message to a server
|
||
REPLACE ao_abrun Queue a read and supersend
|
||
ADD ip_add_server Add a server to the queue
|
||
PROPERTY
|
||
{
|
||
P_QUE hd; Server queue header
|
||
}
|
||
}
|
||
Property
|
||
ipes.hd the head of the queue of server objects that can accept IPC messages. It
|
||
|
||
|
||
should not be read or manipulated by any subclass.
|
||
|
||
|
||
19-2
|
||
|
||
|
||
19 INTER-PROCESS COMMUNICATION
|
||
|
||
|
||
IPCS methods
|
||
J DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID) ;
|
||
Set active.pcb to NULL and supersend the pEstRoy message.
|
||
|
||
|
||
Any non-zero value in active.pcb is a pointer to a message buffer for a received message; this is set in
|
||
the ao_queue method. If active.pcb is non-zero, the superclass dest roy method assumes that it is an I/O
|
||
channel and attempts to close it. Setting it to zero avoids the problem (and no information is "lost" by
|
||
doing so).
|
||
|
||
|
||
AO_INIT Initialise
|
||
|
||
|
||
VOID ao_init (UINT size, UINT num);
|
||
Initialise the IPCS object by performing a number of activities.
|
||
e Initialise an empty server queue in ipcs.hd
|
||
|
||
|
||
e Initialise a message queue of num messages; each message slot will consist of an E_MESSAGE
|
||
header plus a buffer of length size. The queue is initialised using the PLIB function p_minit.
|
||
Note that it is the receiver that specifies the size (and, by implication, the structure) of an inter-
|
||
process message.
|
||
|
||
|
||
e If the creation of the message queue is successful, the object adds itself, with priority
|
||
PRIORITY_ACTIVE_1pcs, to the application manager's active object task queue and then sends
|
||
itself an Ac_QUEUE Message.
|
||
|
||
|
||
Calls p_leave on error.
|
||
|
||
|
||
AO_QUEUE Queue a message read
|
||
VOID ao_queue (VOID) ;
|
||
|
||
|
||
If a message read is currently outstanding, indicated by active.isactive not set to FALSE, the method
|
||
does nothing.
|
||
|
||
|
||
If a message read is not outstanding, it queues a message read by calling p_mreceive, USINg active.stat
|
||
as the completion status word. On completion of the read, the pointer to the received message slot will
|
||
have been written to active.pcb.
|
||
|
||
|
||
If the call to p_mreceive succeeds, active.isactive is set to TRUE. The call to p_mreceive will panic if
|
||
messages have not been initialised or if an asynchronous message receive request is already pending.
|
||
|
||
|
||
J AO CANCEL Cancel read request
|
||
|
||
|
||
VOID ao_cancel (VOID);
|
||
|
||
|
||
If a message read is not currently outstanding, indicated by active.isactive Set to FALSE, the method
|
||
does nothing.
|
||
|
||
|
||
If a message read is outstanding, it calls p_mcance1 to cancel any pending asynchronous request to receive
|
||
a message and then waits (with p_waitstat ON active.stat) for the cancel to complete; it then sets
|
||
active.isactive lO FALSE.
|
||
|
||
|
||
AO_RUN Process a message
|
||
INT ao_run(VOID);
|
||
Pass the message to one of the servers in the server queue.
|
||
|
||
|
||
Scans the items in the server queue until one is found that is prepared to process the type of message that
|
||
has arrived (by comparing the message type with the upper and lower message type limits stored in each
|
||
server's property). Calls p_panic (P_PANIC_P_IPcS_2) if no such server is found.
|
||
|
||
|
||
19-3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
The first server that is prepared to process the message is sent an sv_RUN message under the protection of
|
||
a p_enter (any error in the server's sv_run method is expected to result in a call to p_leave with a non
|
||
zero error number).
|
||
|
||
|
||
On detection of such an error the server is sent an sv_ABRUN message, after which the ao_run method
|
||
itself calls p_leave to propagate the error (thus causing the receipt of an ac_ABRUN message).
|
||
|
||
|
||
If there are no errors, the ac_run method sends an ao_QuEvE message to read another message and then
|
||
returns RUN_ACTIVE_USED.
|
||
|
||
|
||
AO_ABRUN Handle error
|
||
|
||
|
||
VOID ao_abrun (VOID);
|
||
|
||
|
||
Send an ao_QuEuE message to read another message before supersending the ao_aBRUN message.
|
||
|
||
|
||
IP_ADD SERVER Add item to server queue
|
||
|
||
|
||
VOID ip_add_server(PR_SERVER *hand) ;
|
||
|
||
|
||
Add the server object pointed to by hand to the end of the server queue which is anchored in ipcs.had (i.e.
|
||
in the 1pcs object).
|
||
|
||
|
||
Unlike the application manager's queue, there is no priority system. If two servers can both handle a
|
||
message of a particular type, the one that was first added to the server queue will be sent the sv_RuN
|
||
message.
|
||
|
||
|
||
Such a state is, in general, a programming error. Normally, each server is expected to handle a unique
|
||
range of message types. Note that the message types handled by a server fall into a single range.
|
||
|
||
|
||
SERVER
|
||
|
||
|
||
SERVER
|
||
|
||
|
||
destroy
|
||
sv_abrun
|
||
|
||
|
||
sv_init
|
||
|
||
|
||
The server abstract class defines a set of services for processing a received inter-process message.
|
||
|
||
|
||
SERVER must be subclassed to provide at least an sv_run method in order to create a useful server object.
|
||
An example, the link paste server object, is described in the following chapter.
|
||
|
||
|
||
Server objects work closely with an instance of the rpcs class (described above) whose handle is stored in
|
||
the application manager's appman.ipcs.
|
||
|
||
|
||
19-4
|
||
|
||
|
||
19 INTER-PROCESS COMMUNICATION
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file ipc.cl (generated header file ipc.g).
|
||
|
||
|
||
CLASS server root
|
||
{
|
||
|
||
|
||
REPLACE destroy Dequeue and supersend
|
||
ADD sv_abrun=p_dummy Handle leave from sv_run
|
||
ADD sv_init Queue to ipcs
|
||
DEFER sv_run Process message
|
||
PROPERTY
|
||
{
|
||
P_QUE q; Queue header
|
||
UWORD t1; Server type range (lowest msg number)
|
||
UWORD t2; (highest msg number)
|
||
UWORD cid; Client process id, or zero for any process
|
||
}
|
||
}
|
||
Property
|
||
server.q used to add the server to an 1pcs server queue. It should not be accessed
|
||
by any subclass.
|
||
server.tl the lowest message type that is acceptable to this server. It is read by 1pcs
|
||
|
||
|
||
and should not otherwise be accessed.
|
||
|
||
|
||
server.t2 the highest message type that is acceptable to this server. It is read by
|
||
recs and should not otherwise be accessed.
|
||
|
||
|
||
server.cid intended for the storage of a client process id, if any. It is not used by
|
||
either the sERvER or 1pcs Classes and is therefore free for use by any
|
||
subclass. It may be used to store other information, if so required.
|
||
|
||
|
||
SERVER methods
|
||
J DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID);
|
||
|
||
|
||
If the server object sits in an 1pcs server queue, i.e the queue anchored in ipcs.hd, remove it from the
|
||
queue using p_deque. Then supersend a pEsTRoy message.
|
||
|
||
|
||
SV_INIT Initialise
|
||
|
||
|
||
VOID sv_init (UINT tl, UINT t2);
|
||
|
||
|
||
Send an IP_ADD_SERVER message to the object whose handle is stored in the applications manager's (w_am)
|
||
appman.ipcs property field. This object is assumed to be an instance of (a subclass of) the 1pcs class.
|
||
|
||
|
||
Copies t1 and t2 to server.t1 and server.t2 respectively, to set the range of message types acceptable to
|
||
this server. It is assumed that ¢2 is greater than (or equal) to ¢1.
|
||
|
||
|
||
SV_ABRUN Handle error
|
||
VOID sv_abrun (VOID);
|
||
This method does nothing. It is called by recs, following a p_ieave in a server's sv_run method.
|
||
|
||
|
||
A subclass may replace this method to perform specific error handling, over and above that subsequently
|
||
executed in the 1Pcs ao_abrun method.
|
||
|
||
|
||
This method is not expected to call p_leave.
|
||
|
||
|
||
19-5
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Deferred SERVER methods
|
||
|
||
|
||
SV_RUN Process a message
|
||
VOID sv_run(E_MESSAGE *pmess) ;
|
||
Process the message pointed to by pmess.
|
||
|
||
|
||
This message is sent by 1pcs when it has determined that the message that has arrived is within the range
|
||
of types that this server is prepared to process.
|
||
|
||
|
||
19-6
|
||
|
||
|
||
CHAPTER 20
|
||
|
||
|
||
LINK PASTE
|
||
|
||
|
||
Link paste is the term used for the transfer of data from one application to another, for example to transfer
|
||
a database record into the document currently being edited in a word processor. Link paste is initiated by
|
||
the Bring command in a Series 3 application and by a Link command in an MC 200/400 application.
|
||
|
||
|
||
To clarify terminology, this chapter refers to a receiver and a supplier. A receiver is the process which
|
||
asks for the data while the supplier is the process which provides that data. In the context of link-paste, a
|
||
client is synonymous with a receiver while a server is synonymous with a supplier.
|
||
|
||
|
||
The following description applies to applications written for the Series 3 or the MC 200/400. It does not
|
||
apply to applications on the HC, since in this case the system class does not automatically provide access
|
||
to the appropriate system services (see the System Services chapter of this manual) In general, custom
|
||
applications written for the HC will need to provide their own means (usually by explicit inter-process
|
||
messaging) for the receiver to identify a suitable supplier. Once this is done, however, the data may be
|
||
transferred using instances of LInkcL and a subclass of L1nxsv, as described below.
|
||
|
||
|
||
Link paste is implemented by means of inter-process messages sent by the receiver which are handled by
|
||
the supplier of the data. The supplier uses a link paste server object which is generally an instance of a
|
||
subclass of L1nxsv (link server). The receiver generally uses an instance of the L1nxcu (link client) class.
|
||
|
||
|
||
A supplier of data is the passive partner in the transfer in the sense that it replies to IPCS messages sent
|
||
by the receiver. A supplier does not send IPCS messages to the receiver. (See the description of
|
||
p_msendreceivew in the PLIB Reference Manual)
|
||
|
||
|
||
The supplying process must, however, register itself if it is capable of supplying data and must be able to
|
||
specify in which set of data formats it is prepared to supply the data. A Series 3 or MC 200/400
|
||
application may register itself as the current supplier by sending an sy_LINK_SERVER message to an owned
|
||
instance of the system class. For example, if a word processor has a highlighted region of text when it is
|
||
sent into background, it will, in general, register itself as the current supplier at that point.
|
||
|
||
|
||
The range of possible formats are declared, for convenience, in the L1nxsv class definition. Their
|
||
interpretation is significant to the application rather than to the LINKcL and Linxsv classes.
|
||
|
||
|
||
A typical transaction is initiated by the receiver and requires the receiver to perform the following
|
||
activities:-
|
||
|
||
|
||
e It must first locate a process that is prepared to provide data in a suitable format. In the case of an
|
||
application running on either the Series 3 or an MC machine, this is done by sending an
|
||
SY_LINK_PASTE message to an owned instance of the system class to retrieve both the process id
|
||
of the process which is currently registered as a supplier of data and a bit mask of the available
|
||
data formats.
|
||
|
||
|
||
e Jt must, at some stage, create an instance of the L1nxct class and send it an Lc_START message,
|
||
passing the process id of the supplier and the particular format, from those available, in which
|
||
the data is required.
|
||
|
||
|
||
e It sends one or more Lc_GET_DATA messages (to the LINKCL object), passing both the address of a
|
||
buffer which is ready to receive the data and the maximum length of data which can be handled.
|
||
Once data has been received, it can be transferred into the application's own data structures.
|
||
|
||
|
||
e =This should continue until either the available data is exhausted, in which case the transaction is
|
||
automatically terminated, or until the receiver does not wish to receive further data. In this
|
||
second case the receiver must send an Lc_sToP message (to the LINKCL object) to terminate the
|
||
transaction.
|
||
|
||
|
||
20-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
The methods in the L1nxc1i and Linxsv classes and the particular values that their parameters take, in a
|
||
sense, establish a protocol for communication between the receiver and supplier.
|
||
|
||
|
||
Precursors
|
||
|
||
|
||
The reader is assumed to understand:
|
||
e inter-process messaging
|
||
e the SERVER and recs classes
|
||
|
||
|
||
Class diagram
|
||
|
||
|
||
fe oe
|
||
¢ server /
|
||
= Aes.
|
||
\ Patt |
|
||
| aoe —~
|
||
i linkcl /
|
||
)
|
||
ee
|
||
/ linksv /
|
||
as )
|
||
aa
|
||
|
||
|
||
LINKCL
|
||
|
||
|
||
destroy
|
||
lc_start
|
||
|
||
|
||
lc_get_data
|
||
|
||
|
||
lc_stop
|
||
|
||
|
||
The t1nxcu class provides the methods by which a process may initiate a link paste data transfer, receive
|
||
one or more sections of data and, if necessary, terminate the transaction.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file ipc.cl (generated header file ipc.g).
|
||
|
||
|
||
CLASS linkcl root
|
||
The link client
|
||
{
|
||
|
||
|
||
REPLACE destroy Stop the transaction then supersend
|
||
ADD lc_start Start a transaction
|
||
ADD lc_get_data Get a data record
|
||
ADD lc_stop Stop the transaction
|
||
PROPERTY
|
||
{
|
||
UWORD pid; Process ID of link server
|
||
}
|
||
}
|
||
Property
|
||
linkcl.pid the process id of the process that is currently acting as the link paste
|
||
server
|
||
|
||
|
||
20 - 2
|
||
|
||
|
||
20 LINK PASTE
|
||
|
||
|
||
LINKCL methods
|
||
J DESTROY Destroy
|
||
|
||
|
||
VOID destroy (VOID);
|
||
|
||
|
||
Stops any currently outstanding transaction with the link paste server by sending an Lc_sTop message
|
||
before supersending the pEsTRoy message.
|
||
|
||
|
||
LC_ START Initiate a transaction
|
||
|
||
|
||
VOID lc_start (INT pid, INT format);
|
||
|
||
|
||
Initiate a link paste transaction, requesting data of the type specified by format from the current link paste
|
||
server process.
|
||
|
||
|
||
pid is the process id of the current link paste server as retrieved by sending a sy_LINK_PASTE message to
|
||
the receiver's owned system object.
|
||
|
||
|
||
Records the link paste server's process id by setting 1inkcl.pid to pia and then sends a Ty_LINKSV_STEP
|
||
inter-process message, containing the required data format, to the current link paste server process.
|
||
|
||
|
||
Calls p_leave on error.
|
||
|
||
|
||
LC GET DATA Request data
|
||
|
||
|
||
UINT lc_get_data(UBYTE *buf, UINT len);
|
||
Request up to 1en bytes of data to be written to the buffer pointed to by but.
|
||
|
||
|
||
Sends a Ty_LINKSV_STEP inter-process message, containing the buffer pointer and maximum length, to the
|
||
link paste server.
|
||
|
||
|
||
If there is no more data to receive, 1inkcl.pid is set to zero, automatically terminating the transaction. A
|
||
further Lc_sTART message is required in order to receive the data again.
|
||
|
||
|
||
Returns one of:
|
||
e the (positive) length of data written by the link paste server to the buffer,
|
||
e «£ FILE_Eor if there is no more data to receive,
|
||
e £_GEN_FaAIL if the transaction has not been initiated.
|
||
|
||
|
||
Calls p_ieave on all other errors.
|
||
|
||
|
||
LC STOP Terminate a transaction
|
||
VOID lc_stop (VOID) ;
|
||
Terminate any transaction with a link paste server.
|
||
|
||
|
||
It effectively cancels any current transaction and then sets 1inkcl.pid to zero. It is harmless if there is no
|
||
current transaction.
|
||
|
||
|
||
An Lc_START message is required to start a further transaction.
|
||
|
||
|
||
Calls p_leave on error.
|
||
|
||
|
||
20 - 3
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
LINKSV
|
||
|
||
|
||
SERVER LINKSV
|
||
q
|
||
|
||
|
||
buf
|
||
tl len
|
||
t2
|
||
cid
|
||
|
||
|
||
destroy sv_init
|
||
|
||
|
||
sv_abrun sv_run
|
||
ae
|
||
Sv is_set_format
|
||
|
||
|
||
ls_get_data
|
||
|
||
|
||
The t1nxsv abstract class provides the basic mechanisms for supplying, on request, sections of application
|
||
data in one of a variable number of formats.
|
||
|
||
|
||
LINKsv must be subclassed to supply the two deferred methods which depend on the way that the
|
||
application interprets the data formats. The formats are discussed in the HWIM Reference manual.
|
||
|
||
|
||
Class definition
|
||
Defined in sub-category file ipc.cl (generated header file ipc.g).
|
||
|
||
|
||
CLASS linksv server
|
||
The link paste server
|
||
|
||
|
||
{
|
||
|
||
|
||
REPLACE sv_init Supersend with parameters
|
||
REPLACE sv_run Process message
|
||
|
||
DEFER ls_set_format Set the desired format
|
||
DEFER ls_get_data Get a data record
|
||
CONSTANTS
|
||
|
||
|
||
{
|
||
! Message types
|
||
|
||
|
||
TY_LINKSV_STEP 0x21 Link paste step
|
||
TY_LINKSV_DEATH Ox22 Death of client
|
||
! Data formats - formats 0 to 31 inclusive are reserved for use by Psion
|
||
DF_LINK_NATIVE 0 known only to another invocation of the
|
||
supplying application
|
||
DF_LINK_TEXT 1 plain ASCII text
|
||
DF_LINK_TABTEXT 2 ASCII text including tab characters
|
||
DF_LINK_VOICE 3 voice processor data
|
||
DF_LINK_PARAS 4 text with a paragraph structure
|
||
DF_LINK_SPR io) spreadsheet data
|
||
DF_LINK_WRD 6 word processor data (only for Series 3a and later
|
||
machines)
|
||
DF_LINK_AGD q agenda data (only for Series 3a and later machines)
|
||
}
|
||
PROPERTY
|
||
{
|
||
UBYTE *buf; Set by li_get_data
|
||
UWORD len; Set by li_get_data
|
||
}
|
||
}
|
||
Property
|
||
linksv.buf a pointer to data, in the required format, available for copying to the
|
||
client. This is read by the sv_run method and should be set by the
|
||
deferred 1s_get_data method.
|
||
linksv.len the length of the data pointed to by 1inksv.buf. This is read by the
|
||
|
||
|
||
sv_run method and should be set by the deferred 1s_get_data method.
|
||
|
||
|
||
20-4
|
||
|
||
|
||
20 LINK PASTE
|
||
|
||
|
||
LINKSV methods
|
||
|
||
|
||
SV_INIT Initialise
|
||
|
||
|
||
VOID sv_init (VOID) ;
|
||
|
||
|
||
Supersend the sv_tn1tT message, specifying Ty_LINKSv_sTEP and Ty_LINKSvV_DEATH as the lower and
|
||
upper inter-process message types that this server is prepared to handle.
|
||
|
||
|
||
SV_RUN Process a message
|
||
|
||
|
||
VOID sv_run(VOID);
|
||
Process a received link paste inter-process message in the range Ty_LINKSV_STEP tO TY_LINKSV_DEATH.
|
||
|
||
|
||
The handling of an inter-process message is fairly complex and depends on a number of factors, not least
|
||
of which is the type of inter-process message received!
|
||
|
||
|
||
Inter-Process Message ty_uinxsv_sTEP
|
||
|
||
|
||
An inter-process message of type Ty_LINKsv_sTEP is part of a sequence of such messages transferring data
|
||
from the client to the server. The method distinguishes between the first Tty_LINKSV_sTEP inter-process
|
||
message and subsequent inter-process messages of this type.
|
||
|
||
|
||
First ry_tinxsv_step inter-process message
|
||
|
||
|
||
The first ty_LINKSV_STEP inter-process message represents a new transaction and corresponds to
|
||
the client sending an Lc_sTarT message to an instance of its LtnKcL object. The link-server object
|
||
decides that this is the first time if the property server.cid is zero.
|
||
|
||
|
||
The following is done:-
|
||
e The process ID of the client is saved in server.cid.
|
||
|
||
|
||
@ p_logon is called to request that the syssmane process send it a TY_LINKSV_DEATH inter-
|
||
process message if the client terminates.
|
||
|
||
|
||
e The Ty_LINksv_sTEP inter-process message contains the required data format and this is
|
||
passed as the parameter to an Ls_sET_FORMAT message which should register the format in
|
||
which the data is to be provided.
|
||
|
||
|
||
e The inter-process message is freed by calling p_mfree with a reply value of zero.
|
||
|
||
|
||
Subsequent ry_tinxsv_step inter-process messages
|
||
|
||
|
||
Subsequent Ty_LINKSvV_STEP inter-process messages are expected to contain a pointer to a buffer
|
||
and a maximum length in the message data, as set by the LINKcL 1c_get_data method. Two
|
||
situations must be handled - the buffer pointer is zero or non-zero.
|
||
|
||
|
||
Zero buffer pointer
|
||
|
||
|
||
A zero buffer pointer is taken to mean that the client wishes to terminate the link paste
|
||
transaction. This is effectively a cancel and corresponds to the client sending an Lc_stTop
|
||
message to an instance of its LInKcL object.
|
||
|
||
|
||
The following is done:-
|
||
|
||
|
||
e an LS_GET_DATA message is sent with a parameter of -1. The effect of this is to cause the
|
||
deferred 1s_get_data method to tidy and reset the link server object in preparation for a new
|
||
transaction.
|
||
|
||
|
||
® p_logoff is called to cancel the request that the syssmanc process send a Ty_LINKSV_DEATH
|
||
inter-process message on termination of the client.
|
||
|
||
|
||
@ server.cid which contains the process id of the link paste client (i.e. the receiver), is set to
|
||
zero, therefore losing all knowledge of that client
|
||
|
||
|
||
e The inter-process message is freed (p_mfree) returning =_FILE_EoF to the client.
|
||
|
||
|
||
20-5
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
Non-zero buffer pointer
|
||
|
||
|
||
A non-zero buffer is taken to mean that the client is making a request for (more) data. An
|
||
LS_GET_DATA message is sent to retrieve an amount of data not exceeding the maximum length.
|
||
|
||
|
||
If the 1s_get_data method returns a non-zero value:-
|
||
|
||
|
||
e itis assumed that 1inksv.buf and linksv.1len have been set to indicate available data,
|
||
which is copied to the client's buffer.
|
||
|
||
|
||
e The inter-process message is freed (p_mfree) returning a value equal to the length of the data
|
||
copied to the client's buffer.
|
||
|
||
|
||
If the 1s_get_data method returns a zero value:-
|
||
e this is taken to mean that no more data is available.
|
||
|
||
|
||
@ p_logoff is called to cancel the request that the syssmanc process send a Ty_LINKSV_DEATH
|
||
inter-process message on termination of the client.
|
||
|
||
|
||
@ server.cia which contains the process id of the link paste client is set to zero, therefore
|
||
losing all knowledge of that client
|
||
|
||
|
||
e The inter-process message is freed (p_mfree) returning =E_FILE_EoF to the client.
|
||
|
||
|
||
Inter-Process Message ry_utinxsv_pDEATH
|
||
|
||
|
||
An inter-process message of type Ty_LINKSV_DEATH means that the link paste client died or was
|
||
terminated during the inter-process data transfer.
|
||
|
||
|
||
On receipt of this inter-process message, the following is done:-
|
||
e The inter-process message is freed (p_mfree)
|
||
|
||
|
||
e@ server.cid which contains the process id of the link paste client is set to zero, therefore losing
|
||
all knowledge of that client
|
||
|
||
|
||
e an LS_GET_DATA message is sent with a parameter of -1. The effect of this is to cause the deferred
|
||
1s_get_data method to tidy and reset the link server object in preparation for a new transaction.
|
||
|
||
|
||
Deferred LINKSV methods
|
||
LS SET FORMAT Set data format
|
||
|
||
|
||
VOID 1ls_set_format (UINT format) ;
|
||
|
||
|
||
Register the data format in which data is to be provided. For link paste initiated by one of the built-in
|
||
applications, the format will be one of the pr_L1nx_xxx values listed in the L1nxsv class definition.
|
||
|
||
|
||
The method should call p_1eave on error.
|
||
|
||
|
||
LS GET DATA Provide data
|
||
|
||
|
||
INT ls_get_data(UINT len);
|
||
Provide not more than 1en bytes of data in the currently specified format.
|
||
|
||
|
||
A pointer to the data and its length should be written to Linksv.buf and 1inksv.1len respectively. The
|
||
method should return zero if there is no more data available, else a positive number.
|
||
|
||
|
||
A value of -1 for 1en indicates that the client process no longer requires data. In this case the method
|
||
should tidy up and reset any variables so that future Ls_GzT_paTa messages read the data from the start of
|
||
available data.
|
||
|
||
|
||
The method should call p_1eave on error.
|
||
|
||
|
||
20 - 6
|
||
|
||
|
||
INDEX
|
||
|
||
|
||
.trm files
|
||
serial port parameters, 8-11
|
||
ACTIVE class
|
||
AO_ABRUN method, 11-4
|
||
AO_CANCEL method, 11-3
|
||
AO_INIT method, 11-3
|
||
AO_QUEUE method, 11-3
|
||
AO_RUN method, 11-4
|
||
DESTROY method, 11-3
|
||
methods, 11-3
|
||
oop, 11-1
|
||
active objects
|
||
asynchronous I/O devices, 11-1
|
||
class, 11-1
|
||
file, 14-1
|
||
file server and, 11-1
|
||
priorities, 10-2
|
||
return value, 10-3
|
||
scheduling mechanism, 10-6
|
||
scheduling, 10-3
|
||
TIMER, 13-1
|
||
AIDLE class
|
||
AO_INIT method, 12-2
|
||
AO_RUN method, 12-2
|
||
compute intensive tasks, 12-1
|
||
example, 12-3
|
||
idle time computation, 12-3
|
||
methods, 12-2
|
||
oop, 12-1
|
||
pause an operation, 12-3
|
||
AIDLE example
|
||
oop, 12-3
|
||
AM_ADD_TASK
|
||
APPMAN class method, 10-9
|
||
AM_CHANGE_PRI
|
||
APPMAN class method, 10-12
|
||
AM_CLEAN_UP
|
||
APPMAN class method, 10-11
|
||
AM_FINDIMG
|
||
|
||
|
||
AM_INIT
|
||
|
||
APPMAN class method, 10-5
|
||
AM_LOAD_RES_BUF
|
||
|
||
APPMAN class method, 10-10
|
||
AM_LOAD_RESOURCE
|
||
|
||
APPMAN class method, 10-9
|
||
AM_NOTIFY
|
||
|
||
APPMAN class method, 10-10
|
||
AM_NOTIFYERR
|
||
|
||
APPMAN class method, 10-11
|
||
AM_ONLYONE
|
||
|
||
APPMAN class method, 10-12
|
||
|
||
|
||
AM_RSCNAME
|
||
|
||
APPMAN class method, 10-10
|
||
|
||
AM_START
|
||
|
||
APPMAN class method, 10-6
|
||
|
||
AM_STOP
|
||
|
||
APPMAN class method, 10-9
|
||
|
||
AM_WAIT
|
||
|
||
APPMAN class method, 10-6
|
||
|
||
ANIMATOR class
|
||
AO_INIT method, 13-4
|
||
AO_RUN method, 13-4
|
||
methods, 13-4
|
||
oop, 13-3
|
||
|
||
AO_ABRUN
|
||
ACTIVE class method, 11-4
|
||
FACTIVE class method, 14-3
|
||
FMFMT class method, 16-14
|
||
FMSCAN class method, 16-15
|
||
IPCS class method, 19-4
|
||
PNODE class method, 15-4
|
||
PSEL class method, 15-7
|
||
|
||
AO_CANCEL
|
||
ACTIVE class method, 11-3
|
||
BUZSND class method, 13-6
|
||
FACTIVE class method, 14-2
|
||
FCASY class method, 14-12
|
||
IPCS class method, 19-3
|
||
PSEL class method, 15-7
|
||
|
||
AO_INIT
|
||
ACTIVE class method, 11-3
|
||
AIDLE class method, 12-2
|
||
ANIMATOR class method, 13-4
|
||
BUZSND class method, 13-5
|
||
FACTIVE class method, 14-2
|
||
IPCS class method, 19-3
|
||
PSEL class method, 15-7
|
||
TIMER class method, 13-2
|
||
|
||
AO_QUEUE
|
||
ACTIVE class method, 11-3
|
||
BUZSND class method, 13-6
|
||
FCASY class method, 14-12
|
||
FCSYNC class method, 14-15
|
||
FNODE class method, 14-9
|
||
FSCAN class method, 14-5
|
||
IPCS class method, 19-3
|
||
TIMER class method, 13-2
|
||
|
||
AO_RUN
|
||
ACTIVE class method, 11-4
|
||
AIDLE class method, 12-2
|
||
ANIMATOR class method, 13-4
|
||
BUZSND class method, 13-6
|
||
FCASY class method, 14-13
|
||
FMFMT class method, 16-13
|
||
FMMK class method, 16-12
|
||
FNODE class method, 14-9
|
||
FSCAN class method, 14-5
|
||
IPCS class method, 19-3
|
||
|
||
APPMAN class
|
||
AM_ADD_TASK method, 10-9
|
||
AM_CHANGE__ PRI method, 10-12
|
||
AM_CLEAN_UP method, 10-11
|
||
AM_FINDIMG method, 10-11
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
AM_INIT method, 10-5 cl_remove
|
||
AM_LOAD_RES_BUF method, 10-10 CLEANUP class function, 9-6
|
||
AM_LOAD_RESOURCE method, 10-9 CL_REMOVE
|
||
|
||
|
||
AM_NOTIFY method, 10-10
|
||
AM_NOTIFYERR method, 10-11
|
||
AM_ONLYONE method, 10-12
|
||
AM_RSCNAME method, 10-10
|
||
AM_START method, 10-6
|
||
AM_STOP method, 10-9
|
||
AM_WAIT, 10-6
|
||
|
||
definition, 10-4
|
||
|
||
diagram, 10-4
|
||
|
||
methods, 10-5
|
||
|
||
|
||
CLEANUP class method, 9-3
|
||
CL_SET_LEVEL
|
||
|
||
CLEANUP class method, 9-4
|
||
class
|
||
|
||
ACTIVE, 11-1
|
||
|
||
AIDLE, 12-1
|
||
|
||
ANIMATOR, 13-3
|
||
|
||
|
||
application manager definition, 10-4
|
||
application manager diagram, 10-4
|
||
application manager, 10-1
|
||
|
||
|
||
oop, 10-1 application manager property, 10-5
|
||
property, 10-5 BFILE, 8-2
|
||
ARRAY VARIABLE binary files, 8-1
|
||
classes, 5-1 BUZSND, 13-4
|
||
asynchronous cleanup, 9-1
|
||
I/O devices active object, 11-1 editable documents, 6-1
|
||
BFILE class EPFLAT, 6-7
|
||
DESTROY method, 8-3 EPROOT, 6-2
|
||
FI_CLOSE method, 8-3 EPSEG, 6-10
|
||
FI_OPEN method, 8-3 FACTIVE, 14-1
|
||
FI_READ method, 8-3 FCASY, 14-11
|
||
FL_REWIND method, 8-4 FCSYNC, 14-14
|
||
FL_SENSE_DATA method, 8-4 FMAN, 16-2
|
||
FL_SET_BUF_LEN method, 8-3 FMFMT, 16-13
|
||
methods, 8-3 FMMK, 16-12
|
||
oop class, 8-2 FMSCAN, 16-14
|
||
BINARY FILE FMSRC, 16-17
|
||
classes, 8-1 FMTARG, 16-18
|
||
bring FNODE, 14-8
|
||
IPCS, 20-5 FSCAN, 14-3
|
||
oop, 20-1 idle object, 12-1
|
||
BUZSND class IPCS, 19-2
|
||
AO_CANCEL method, 13-6 LINKCL, 20-2
|
||
AO_INIT method, 13-5 LINKSV, 20-4
|
||
AO_QUEUE method, 13-6 PNODE, 15-3
|
||
AO_RUN method, 13-6 PSEL, 15-4
|
||
methods, 13-5 PSELVAR, 15-2
|
||
oop, 13-4 resource files, 7-1
|
||
cl_add ROOT, 2-1
|
||
CLEANUP class function, 9-4 SCAN, 17-1
|
||
CL_ADD SERFILE, 8-11
|
||
CLEANUP class method, 9-3 SERVER, 19-4
|
||
cl_add_alloc SGBUF, 4-1
|
||
CLEANUP class function, 9-5 SYSTEM, 18-1
|
||
cl_add_dyl TIME, 3-1
|
||
CLEANUP class function, 9-5 TIMER, 13-1, 13-2
|
||
cl_add_iochan TLVDATA, 8-8
|
||
CLEANUP class function, 9-5 TLVFILE, 8-4
|
||
cl_add_object VAFIX, 5-9
|
||
CLEANUP class function, 9-4 VAFLAT, 5-14
|
||
cl_add_shared variable array classes, 5-1
|
||
CLEANUP class function, 9-5 VAROOT, 5-3
|
||
cl_clean_item VASEG, 5-16
|
||
CLEANUP class function, 9-6 VASTR, 5-11
|
||
CL_CLEAN_ITEM VAXVAR, 5-18
|
||
CLEANUP class method, 9-3 VAXVARS, 5-21
|
||
CL_CLEAN_LEVEL class diagrams
|
||
CLEANUP class method, 9-4 OLIB hierarchy, 1-3
|
||
CL_INIT OLIB library, 1-3
|
||
CLEANUP class method, 9-3 classes
|
||
|
||
|
||
OLIB library overview, 1-1
|
||
|
||
|
||
OLIB library using, 1-2
|
||
CLEANUP class
|
||
cl_add function, 9-4
|
||
CL_ADD method, 9-3
|
||
cl_add_alloc function, 9-5
|
||
cl_add_dyl function, 9-5
|
||
cl_add_iochan function, 9-5
|
||
cl_add_object function, 9-4
|
||
cl_add_shared function, 9-5
|
||
cl_clean_item function, 9-6
|
||
|
||
|
||
CL_CLEAN_ITEM method, 9-3
|
||
CL_CLEAN_LEVEL method, 9-4
|
||
|
||
|
||
CL_INIT method, 9-3
|
||
cl_remove function, 9-6
|
||
CL_REMOVE method, 9-3
|
||
|
||
|
||
CL_SET_LEVEL method, 9-4
|
||
|
||
|
||
DESTROY method, 9-3
|
||
functions convenience, 9-4
|
||
methods, 9-3
|
||
oop, 9-1
|
||
compute intensive tasks
|
||
AIDLE class, 12-1
|
||
DatCommandPtr
|
||
magic static, 10-11
|
||
DESTROY
|
||
ACTIVE class method, 11-3
|
||
BFILE class method, 8-3
|
||
CLEANUP class method, 9-3
|
||
EPFLAT class method, 6-8
|
||
IPCS class method, 19-3
|
||
LINKCL class method, 20-3
|
||
ROOT class method, 2-2
|
||
RSCFILE class method, 7-2
|
||
SERVER class method, 19-5
|
||
SGBUF class method, 4-2
|
||
VAROOT class method, 5-4
|
||
documents editable
|
||
classes, 6-1
|
||
DYL
|
||
|
||
|
||
EP_COPY_TO_FRONT
|
||
|
||
EPROOT class method, 6-5
|
||
EP_DELETE
|
||
|
||
EPFLAT class method, 6-9
|
||
|
||
EPSEG class method, 6-11
|
||
EP_EXTRACT
|
||
|
||
EPFLAT class method, 6-9
|
||
|
||
EPSEG class method, 6-11
|
||
EP_INIT
|
||
|
||
EPFLAT class method, 6-8
|
||
|
||
EPSEG class method, 6-10
|
||
EP_INSERT
|
||
|
||
EPFLAT class method, 6-8
|
||
|
||
EPSEG class method, 6-11
|
||
EP_MOD_CHARS
|
||
|
||
EPROOT class method, 6-6
|
||
EP_PARA_COUNT
|
||
|
||
EPROOT class method, 6-4
|
||
EP_PASTE
|
||
|
||
EPROOT class method, 6-6
|
||
EP_SCAN_BLOCK
|
||
|
||
EPROOT class method, 6-4
|
||
EP_SCAN_PARA
|
||
|
||
EPROOT class method, 6-4
|
||
EP_SCAN_WORD
|
||
|
||
EPROOT class method, 6-4
|
||
EP_SENSE_CHARS
|
||
|
||
EPFLAT class method, 6-8
|
||
|
||
EPSEG class method, 6-11
|
||
EP_SENSE_LEN
|
||
|
||
EPFLAT class method, 6-8
|
||
|
||
EPSEG class method, 6-11
|
||
EP_SENSE_TEXT
|
||
|
||
EPROOT class method, 6-6
|
||
EP_SET_TEXT
|
||
|
||
EPROOT class method, 6-3
|
||
EP_WORD COUNT
|
||
|
||
EPROOT class method, 6-4
|
||
EPFLAT class
|
||
|
||
|
||
OLIB library introduction, 1-1
|
||
|
||
|
||
editable documents class
|
||
|
||
oop, 6-1
|
||
EF_GRANULARITY
|
||
|
||
EPFLAT class method, 6-9
|
||
EF_SENSE_BUF
|
||
|
||
EPFLAT class method, 6-9
|
||
EP_ADD_PARA
|
||
|
||
EPROOT class method, 6-5
|
||
EP_BACK_ CHARS
|
||
|
||
EPFLAT class method, 6-8
|
||
|
||
EPSEG class method, 6-11
|
||
EP_CAPACITY
|
||
|
||
EPFLAT class method, 6-9
|
||
|
||
EPROOT class method, 6-6
|
||
EP_CLEAR
|
||
|
||
EPFLAT class method, 6-9
|
||
|
||
EPSEG class method, 6-11
|
||
EP_COMPRESS
|
||
|
||
EPFLAT class method, 6-9
|
||
|
||
EPSEG class method, 6-11
|
||
EP_COPY_INDENT
|
||
|
||
EPROOT class method, 6-5
|
||
EP_COPY_TO_BACK
|
||
|
||
EPROOT class method, 6-5
|
||
|
||
|
||
DESTROY method, 6-8
|
||
|
||
|
||
EF_GRANULARITY method, 6-9
|
||
|
||
|
||
EF_SENSE_BUF method, 6-9
|
||
EP_BACK_CHARS method, 6-8
|
||
EP_CAPACITY method, 6-9
|
||
EP_CLEAR method, 6-9
|
||
EP_COMPRESS method, 6-9
|
||
EP_DELETE method, 6-9
|
||
EP_EXTRACT method, 6-9
|
||
EP_INIT method, 6-8
|
||
EP_INSERT method, 6-8
|
||
EP_SENSE_CHARS method, 6-8
|
||
EP_SENSE_LEN method, 6-8
|
||
methods, 6-8
|
||
|
||
oop class, 6-7
|
||
|
||
|
||
EPROOT class
|
||
|
||
|
||
EP_ADD_PARA method, 6-5
|
||
EP_CAPACITY method, 6-6
|
||
EP_COPY_INDENT method, 6-5
|
||
|
||
|
||
EP_COPY_TO_BACK method, 6-5
|
||
EP_COPY_TO_FRONT method, 6-5
|
||
|
||
|
||
EP_MOD_CHARS method, 6-6
|
||
EP_PARA_COUNT method, 6-4
|
||
EP_PASTE method, 6-6
|
||
EP_SCAN_BLOCK method, 6-4
|
||
|
||
|
||
INDEX
|
||
|
||
|
||
iii
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
EP_SCAN_PARA method, 6-4
|
||
EP_SCAN_WORD method, 6-4
|
||
EP_SENSE_TEXT method, 6-6
|
||
EP_SET_TEXT method, 6-3
|
||
|
||
|
||
EP_WORD COUNT method, 6-4
|
||
|
||
|
||
methods deferred, 6-6
|
||
|
||
methods, 6-3
|
||
|
||
oop class, 6-2
|
||
EPSEG class
|
||
|
||
|
||
EP_BACK_CHARS method, 6-11
|
||
|
||
|
||
EP_CLEAR method, 6-11
|
||
EP_COMPRESS method, 6-11
|
||
EP_DELETE method, 6-11
|
||
EP_EXTRACT method, 6-11
|
||
EP_INIT method, 6-10
|
||
EP_INSERT method, 6-11
|
||
|
||
|
||
EP_SENSE_CHARS method, 6-11
|
||
|
||
|
||
EP_SENSE_LEN method, 6-11
|
||
methods, 6-10
|
||
oop class, 6-10
|
||
error handling
|
||
OLIB library, 1-4
|
||
OLIB library panics, 1-5
|
||
FA_CLOSE
|
||
FACTIVE class method, 14-3
|
||
FCASY class method, 14-13
|
||
FNODE class method, 14-10
|
||
FSCAN class method, 14-6
|
||
FACTIVE class
|
||
AO_ABRUN method, 14-3
|
||
AO_CANCEL method, 14-2
|
||
AO_INIT method, 14-2
|
||
FA_CLOSE method, 14-3
|
||
methods, 14-2
|
||
oop, 14-1
|
||
FC_OPEN
|
||
FCASY class method, 14-13
|
||
FC_REQUEST_COMP
|
||
deferred method, 14-14
|
||
|
||
|
||
FCASY class method deferred, 14-14
|
||
|
||
|
||
FMSRC class method, 16-17
|
||
FMTARG class method, 16-18
|
||
FC_WRITE
|
||
FCASY class method, 14-12
|
||
FCSYNC class method, 14-15
|
||
FCASY class
|
||
AO_CANCEL method, 14-12
|
||
AO_QUEUE method, 14-12
|
||
AO_RUN method, 14-13
|
||
FA_CLOSE method, 14-13
|
||
FC_OPEN method, 14-13
|
||
FC_WRITE method, 14-12
|
||
methods deferred, 14-14
|
||
methods, 14-12
|
||
oop, 14-11
|
||
FCASY sub-class
|
||
oop, 14-1
|
||
FCSYNC class
|
||
AO_QUEUE method, 14-15
|
||
FC_WRITE method, 14-15
|
||
methods, 14-15
|
||
oop, 14-14
|
||
FCSYNC sub-class
|
||
oop, 14-1
|
||
|
||
|
||
FI_CLOSE
|
||
|
||
BFILE class method, 8-3
|
||
FI_OPEN
|
||
|
||
BFILE class method, 8-3
|
||
|
||
TLVFILE class method, 8-6
|
||
FI_READ
|
||
|
||
BFILE class method, 8-3
|
||
file
|
||
|
||
active object, 14-1
|
||
FILE BINARY
|
||
|
||
classes, 8-1
|
||
file I/O
|
||
|
||
active objects and, 11-1
|
||
file lists
|
||
|
||
oop, 15-1
|
||
file management
|
||
|
||
oop, 16-1
|
||
file manager
|
||
|
||
example code, 16-19
|
||
file scan local
|
||
|
||
oop, 17-1
|
||
file server
|
||
|
||
active objects and, 11-1
|
||
files
|
||
|
||
type-length-value, 8-4
|
||
filing system
|
||
|
||
nodes, 14-8
|
||
FL_COUNT
|
||
|
||
TLVFILE class method, 8-6
|
||
FL_DELREC
|
||
|
||
TLVFILE class method, 8-7
|
||
FL_READ_BY_TYPE
|
||
|
||
TLVFILE class method, 8-7
|
||
FL_REPLACE
|
||
|
||
TLVFILE class method, 8-7
|
||
FL_REWIND
|
||
|
||
BFILE class method, 8-4
|
||
|
||
TLVFILE class method, 8-6
|
||
FL_SENSE_DATA
|
||
|
||
BFILE class method, 8-4
|
||
FL_SENSE_REC
|
||
|
||
TLVFILE class method, 8-7
|
||
FL_SET_BUF_LEN
|
||
|
||
BFILE class method, 8-3
|
||
FL_SET_REC
|
||
|
||
TLVFILE class method, 8-6
|
||
FL_WRITE_REC
|
||
|
||
TLVFILE class method, 8-6
|
||
FMAN class
|
||
|
||
file management, 16-1
|
||
FMAN_ATTRIB method, 16-8
|
||
FMAN_CANCEL method, 16-4
|
||
|
||
|
||
FMAN_COPY method, 16-5
|
||
FMAN_COPYDEV method, 16-7
|
||
FMAN_DELETE method, 16-5
|
||
|
||
|
||
16-11
|
||
FMAN_FORMAT method, 16-8
|
||
FMAN_INFO method, 16-8
|
||
FMAN_INIT method, 16-4
|
||
FMAN_MAKE method, 16-7
|
||
FMAN_NAME method, 16-8
|
||
|
||
|
||
FMAN_COMPLETE deferred method, 16-9
|
||
|
||
|
||
FMAN_ERROR deferred method, 16-11
|
||
FMAN_FILEEXIST deferred method,
|
||
|
||
|
||
FMAN_NEWNAME deferred method,
|
||
16-10
|
||
FMAN_REMOVE method, 16-7
|
||
FMAN_RENAME method, 16-6
|
||
FMAN_UPDATE deferred method, 16-11
|
||
methods deferred, 16-9
|
||
methods, 16-4
|
||
oop, 16-2
|
||
FMAN_ATTRIB
|
||
FMAN class method, 16-8
|
||
FMAN_CANCEL
|
||
FMAN class method, 16-4
|
||
FMAN_COMPLETE
|
||
FMAN class method deferred, 16-9
|
||
FMAN_COPY
|
||
FMAN class method, 16-5
|
||
FMAN_COPYDEV
|
||
FMAN class method, 16-7
|
||
FMAN_DELETE
|
||
FMAN class method, 16-5
|
||
FMAN_ERROR
|
||
FMAN class method deferred, 16-11
|
||
FMAN_FILEEXIST
|
||
FMAN class method deferred, 16-11
|
||
FMAN_FORMAT
|
||
FMAN class method, 16-8
|
||
FMAN_INFO
|
||
FMAN class method, 16-8
|
||
FMAN_INIT
|
||
FMAN class method, 16-4
|
||
FMAN_MAKE
|
||
FMAN class method, 16-7
|
||
FMAN_NAME
|
||
FMAN class method, 16-8
|
||
FMAN_NEWNAME
|
||
FMAN class method deferred, 16-10
|
||
FMAN_REMOVE
|
||
FMAN class method, 16-7
|
||
FMAN_RENAME
|
||
FMAN class method, 16-6
|
||
FMAN_UPDATE
|
||
FMAN class method deferred, 16-11
|
||
FMFMT class
|
||
AO_ABRUN method, 16-14
|
||
AO_RUN method, 16-13
|
||
methods, 16-13
|
||
oop, 16-13
|
||
FMFMT sub-class
|
||
oop, 16-1
|
||
FMMK class
|
||
AO_RUN method, 16-12
|
||
methods, 16-12
|
||
oop, 16-12
|
||
FMMkK sub-class
|
||
oop, 16-1
|
||
FMSCAN class
|
||
AO_ABRUN method, 16-15
|
||
FS_DIRNAME method, 16-16
|
||
FS_END_DIRLIST method, 16-16
|
||
FS_FILENAME method, 16-15
|
||
FS_FSCAN_END method, 16-16
|
||
methods, 16-15
|
||
oop, 16-14
|
||
|
||
|
||
INDEX
|
||
|
||
|
||
FMSCAN sub-class
|
||
oop, 16-1
|
||
FMSRC class
|
||
FC_REQUEST_COMP method, 16-17
|
||
methods, 16-17
|
||
oop, 16-17
|
||
FMSRC sub-class
|
||
oop, 16-1
|
||
FMTARG class
|
||
FC_REQUEST_COMP method, 16-18
|
||
methods, 16-18
|
||
oop, 16-18
|
||
FMTARG sub-class
|
||
oop, 16-1
|
||
FN_END_LIST
|
||
FNODE class method deferred, 14-10
|
||
PNODE class method, 15-4
|
||
FN_LIST
|
||
FNODE class method, 14-10
|
||
FN_NODENAME
|
||
FNODE class method deferred, 14-10
|
||
PNODE class method, 15-4
|
||
FNODE class
|
||
AO_QUEUE method, 14-9
|
||
AO_RUN method, 14-9
|
||
FA_CLOSE method, 14-10
|
||
FN_END_LIST deferred method, 14-10
|
||
FN_LIST method, 14-10
|
||
FN_NODENAME deferred method, 14-10
|
||
methods deferred, 14-10
|
||
methods, 14-9
|
||
oop, 14-8
|
||
FENODE sub-class
|
||
oop, 14-1
|
||
FS_DIRNAME
|
||
FMSCAN class method, 16-16
|
||
FSCAN class method deferred, 14-7
|
||
PSEL class method, 15-8
|
||
FS_END_DIRLIST
|
||
FMSCAN class method, 16-16
|
||
FSCAN class method deferred, 14-8
|
||
FS_FILENAME
|
||
FMSCAN class method, 16-15
|
||
FSCAN class method deferred, 14-7
|
||
PSEL class method, 15-8
|
||
FS_FSCAN
|
||
FSCAN class method, 14-6
|
||
FS_FSCAN_END
|
||
FMSCAN class method, 16-16
|
||
FSCAN class method deferred, 14-7
|
||
PSEL class method, 15-8
|
||
FS_MATCHNAME
|
||
FSCAN class method, 14-6
|
||
FSCAN class
|
||
AO_QUEUE method, 14-5
|
||
AO_RUN method, 14-5
|
||
FA_CLOSE method, 14-6
|
||
FS_DIRNAME deferred method, 14-7
|
||
FS_END_DIRLIST deferred method, 14-8
|
||
FS_FILENAME deferred method, 14-7
|
||
FS_FSCAN method, 14-6
|
||
FS_FSCAN_END method, 14-7
|
||
FS_MATCHNAME method, 14-6
|
||
methods deferred, 14-7
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
methods, 14-5
|
||
oop, 14-3
|
||
FSCAN sub-class
|
||
oop, 14-1
|
||
functions
|
||
CLEANUP class convenience, 9-4
|
||
HWIM
|
||
active object, 11-1
|
||
application manager class, 10-1
|
||
idle object, 12-1
|
||
I/O asynchronous
|
||
active object, 11-1
|
||
idle object
|
||
class, 12-1
|
||
IDLE OBJECT
|
||
class, 12-1
|
||
idle time
|
||
AIDLE class computation, 12-3
|
||
INTER-PROCESS COMMUNICATIONS
|
||
class, 19-1
|
||
IP_ADD_SERVER
|
||
IPCS class method, 19-4
|
||
IPCS
|
||
bring, 20-5
|
||
class, 19-1
|
||
link paste, 20-5
|
||
IPCS class
|
||
AO_ABRUN method, 19-4
|
||
AO_CANCEL method, 19-3
|
||
AO_INIT method, 19-3
|
||
AO_QUEUE method, 19-3
|
||
AO_RUN method, 19-3
|
||
DESTROY method, 19-3
|
||
IP_ADD_SERVER method, 19-4
|
||
methods, 19-3
|
||
services, 19-2
|
||
LC_GET_DATA
|
||
LINKCL class method, 20-3
|
||
LC_START
|
||
LINKCL class method, 20-3
|
||
LC_STOP
|
||
LINKCL class method, 20-3
|
||
library
|
||
OLIB DYL introduction, 1-1
|
||
link paste
|
||
IPCS, 20-5
|
||
LINK PASTE
|
||
classes, 20-1
|
||
LINKCL class
|
||
DESTROY class method, 20-3
|
||
LC_GET_DATA class method, 20-3
|
||
LC_START class method, 20-3
|
||
LC_STOP class method, 20-3
|
||
methods, 20-3
|
||
services, 20-2
|
||
LINKSYV class
|
||
LS_GET_DATA class method, 20-6
|
||
LS_SET_FORMAT class method, 20-6
|
||
methods deferred, 20-6
|
||
methods, 20-5
|
||
services, 20-4
|
||
SV_INIT class method, 20-5
|
||
SV_RUN class method, 20-5
|
||
|
||
|
||
LOC
|
||
filing system node, 14-8, 17-1
|
||
LOCS class
|
||
LS_FILENAME deferred method, 17-3
|
||
LS_MATCHNAME method, 17-3
|
||
LS_SCAN method, 17-3
|
||
methods deferred, 17-3
|
||
methods, 17-3
|
||
LS_FILENAME
|
||
LOCS class method deferred, 17-3
|
||
LS_GET_DATA
|
||
LINKSV class method deferred, 20-6
|
||
LS_MATCHNAME
|
||
LOCS class method, 17-3
|
||
LS_SCAN
|
||
LOCS class method, 17-3
|
||
LS_SET_FORMAT
|
||
LINKSV class method deferred, 20-6
|
||
magic static
|
||
DatCommandPtr, 10-11
|
||
manager
|
||
application class, 10-1
|
||
method function
|
||
OLIB long parameters, 1-3
|
||
OLIB prototypes, 1-2
|
||
methods
|
||
ACTIVE class, 11-3
|
||
AIDLE class, 12-2
|
||
ANIMATOR class, 13-4
|
||
APPMAN class, 10-5
|
||
BFILE class, 8-3
|
||
BUZSND class, 13-5
|
||
CLEANUP class, 9-3
|
||
EPFLAT class, 6-8
|
||
EPROOT class deferred, 6-6
|
||
EPROOT class, 6-3
|
||
EPSEG class, 6-10
|
||
FACTIVE class, 14-2
|
||
FCASY class deferred, 14-14
|
||
FCASY class, 14-12
|
||
FCSYNC class, 14-15
|
||
FMAN class deferred, 16-9
|
||
FMAN class, 16-4
|
||
FMFMT class, 16-13
|
||
FMMkK class, 16-12
|
||
FMSCAN class, 16-15
|
||
FMSRC class, 16-17
|
||
FMTARG class, 16-18
|
||
FNODE class deferred, 14-10
|
||
FNODE class, 14-9
|
||
FSCAN class deferred, 14-7
|
||
FSCAN class, 14-5
|
||
IPCS class, 19-3
|
||
LINKCL class, 20-3
|
||
LINKSV class deferred, 20-6
|
||
LINKSV class, 20-5
|
||
LOCS class deferred, 17-3
|
||
LOCS class, 17-3
|
||
PNODE class, 15-4
|
||
PSEL class deferred, 15-11
|
||
PSEL class, 15-7
|
||
PSELVAR class, 15-3
|
||
ROOT class, 2-2
|
||
RSCFILE class, 7-2
|
||
|
||
|
||
SERFILE class, 8-13
|
||
SERVER class deferred, 19-6
|
||
SERVER class, 19-5
|
||
|
||
SGBUF class, 4-2
|
||
|
||
SYSTEM class, 18-2
|
||
|
||
TIME class, 3-3
|
||
|
||
TIMER class, 13-2
|
||
TLVDATA class deferred, 8-10
|
||
TLVDATA class, 8-9
|
||
TLVFILE class, 8-6
|
||
|
||
VAFIX class, 5-10
|
||
|
||
VAFLAT class, 5-15
|
||
VAROOT class deferred, 5-7
|
||
VAROOT class, 5-4
|
||
|
||
VASEG class, 5-17
|
||
|
||
VASTER class, 5-12
|
||
VAXVAR class, 5-20
|
||
VAXVARS class, 5-22
|
||
|
||
|
||
node
|
||
|
||
|
||
filing systems, 14-8
|
||
|
||
|
||
OLIB
|
||
|
||
|
||
class diagrams, 1-3
|
||
|
||
class hierarchy, 1-3
|
||
|
||
classes overview, 1-1
|
||
|
||
classes using, 1-2
|
||
|
||
error handling, 1-4
|
||
|
||
error numbers panics, 1-5
|
||
|
||
library introduction, 1-1
|
||
|
||
method function long parameters, 1-3
|
||
method function prototypes, 1-2
|
||
PLIB basis, 1-1
|
||
|
||
|
||
ACTIVE class HWIM, 11-1
|
||
|
||
ACTIVE class methods, 11-3
|
||
|
||
active object priorities, 10-2
|
||
|
||
active object return value, 10-3
|
||
|
||
active object scheduling, 10-3
|
||
|
||
active object scheduling mechanism, 10-6
|
||
AIDLE class example, 12-3
|
||
|
||
AIDLE class HWIM, 12-1
|
||
|
||
AIDLE class idle time computation, 12-3
|
||
AIDLE class methods, 12-2
|
||
|
||
AIDLE class pause operation, 12-3
|
||
ANIMATOR class methods, 13-4
|
||
application manager class definition, 10-4
|
||
application manager class diagram, 10-4
|
||
application manager class HWIM, 10-1
|
||
application manager class property, 10-5
|
||
APPMAN class methods, 10-5
|
||
|
||
BFILE class, 8-2
|
||
|
||
BFILE class methods, 8-3
|
||
|
||
bring, 20-1
|
||
|
||
BUZSND class methods, 13-5
|
||
CLEANUP class functions convenience, 9-4
|
||
CLEANUP class methods, 9-3
|
||
|
||
EPFLAT class, 6-7
|
||
|
||
EPFLAT class methods, 6-8
|
||
|
||
EPROOT class, 6-2
|
||
|
||
EPROOT class deferred methods, 6-6
|
||
EPROOT class methods, 6-3
|
||
|
||
EPSEG class, 6-10
|
||
|
||
EPSEG class methods, 6-10
|
||
|
||
FACTIVE class, 14-1
|
||
|
||
FACTIVE class methods, 14-2
|
||
|
||
|
||
INDEX
|
||
|
||
|
||
FCASY class, 14-11
|
||
|
||
FCASY class deferred methods, 14-14
|
||
FCASY class methods, 14-12
|
||
FCASY sub-class, 14-1
|
||
|
||
FCSYNC class, 14-14
|
||
|
||
FCSYNC class methods, 14-15
|
||
FCSYNC sub-class, 14-1
|
||
|
||
file active object, 14-1
|
||
|
||
file lists, 15-1
|
||
|
||
file management, 16-1
|
||
|
||
file manager example code, 16-19
|
||
file scan local, 17-1
|
||
|
||
FMAN class, 16-2
|
||
|
||
FMAN class deferred methods, 16-9
|
||
FMAN class methods, 16-4
|
||
FMFMT class, 16-13
|
||
|
||
FMFMT class methods, 16-13
|
||
FMFMT sub-class, 16-1
|
||
|
||
FMMkK class, 16-12
|
||
|
||
FMMkK class methods, 16-12
|
||
FMMkK sub-class, 16-1
|
||
|
||
FMSCAN class, 16-14
|
||
|
||
FMSCAN class methods, 16-15
|
||
FMSCAN sub-class, 16-1
|
||
|
||
FMSRC class, 16-17
|
||
|
||
FMSRC class methods, 16-17
|
||
FMSRC sub-class, 16-1
|
||
|
||
FMTARG class, 16-18
|
||
|
||
FMTARG class methods, 16-18
|
||
FMTARG sub-class, 16-1
|
||
|
||
FNODE class, 14-8
|
||
|
||
FNODE class deferred methods, 14-10
|
||
FNODE class methods, 14-9
|
||
FNODE sub-class, 14-1
|
||
|
||
FSCAN class, 14-3
|
||
|
||
FSCAN class deferred methods, 14-7
|
||
FSCAN class methods, 14-5
|
||
FSCAN sub-class, 14-1
|
||
inter-process communications, 19-1
|
||
IPCS, 19-1
|
||
|
||
IPCS bring, 20-5
|
||
|
||
IPCS class, 19-2
|
||
|
||
IPCS class methods, 19-3
|
||
|
||
IPCS link paste, 20-5
|
||
|
||
link paste, 20-1
|
||
|
||
LINKCL class, 20-2
|
||
|
||
LINKCL class methods, 20-3
|
||
LINKSV class, 20-4
|
||
|
||
LINKSYV class deferred methods, 20-6
|
||
LINKSV class methods, 20-5
|
||
LOCS class deferred methods, 17-3
|
||
LOCS class methods, 17-3
|
||
|
||
PNODE class, 15-3
|
||
|
||
PNODE class methods, 15-4
|
||
|
||
PSEL class, 15-4
|
||
|
||
PSEL class deferred methods, 15-11
|
||
PSEL class methods, 15-7
|
||
PSELVAR class, 15-2
|
||
|
||
PSELVAR class methods, 15-3
|
||
ROOT class, 2-1
|
||
|
||
ROOT class DESTROY method, 2-2
|
||
ROOT class methods, 2-2
|
||
RSCFILE class methods, 7-2
|
||
SCAN class, 17-1
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
SERFILE class, 8-11
|
||
|
||
SERFILE class methods, 8-13
|
||
|
||
SERVER class, 19-4
|
||
|
||
SERVER class deferred methods, 19-6
|
||
|
||
SERVER class methods, 19-5
|
||
|
||
SGBUF class, 4-1
|
||
|
||
SGBUF class methods, 4-2
|
||
|
||
SYSTEM class, 18-1
|
||
|
||
SYSTEM class methods, 18-2
|
||
|
||
system services, 18-1
|
||
|
||
TIME class, 3-1
|
||
|
||
TIME class methods, 3-3
|
||
|
||
TIMER active object, 13-1
|
||
|
||
TIMER class, 13-1
|
||
|
||
TIMER class methods, 13-2
|
||
|
||
TLVDATA class, 8-8
|
||
|
||
TLVDATA class defered methods, 8-10
|
||
|
||
TLVDATA class methods, 8-9
|
||
|
||
TLVFILE class, 8-4
|
||
|
||
TLVFILE class methods, 8-6
|
||
|
||
type-length-value files, 8-4
|
||
|
||
VAFIX class, 5-9
|
||
|
||
VAFIX class methods, 5-10
|
||
|
||
VAFLAT class, 5-14
|
||
|
||
VAFLAT class methods, 5-15
|
||
|
||
VAROOT class, 5-3
|
||
|
||
VAROOT class deferred methods, 5-7
|
||
|
||
VAROOT class methods, 5-4
|
||
|
||
VASEG class, 5-16
|
||
|
||
VASEG class methods, 5-17
|
||
|
||
VASTR class, 5-11
|
||
|
||
VASTR class methods, 5-12
|
||
|
||
VAXVAR class, 5-18
|
||
|
||
VAXVAR class methods, 5-20
|
||
|
||
VAXVARS class, 5-21
|
||
|
||
VAXVARS class methods, 5-22
|
||
panics
|
||
|
||
OLIB error numbers, 1-5
|
||
pause operation
|
||
|
||
AIDLE example, 12-3
|
||
PLIB
|
||
|
||
OLIB relationship to, 1-1
|
||
PNODE class
|
||
|
||
AO_ABRUN method, 15-4
|
||
|
||
FN_END_LIST method, 15-4
|
||
|
||
FN_NODENAME method, 15-4
|
||
|
||
methods, 15-4
|
||
|
||
oop, 15-3
|
||
PS_ASCEND_PATH
|
||
|
||
PSEL class method, 15-9
|
||
PS_DESCEND_PATH
|
||
|
||
PSEL class method, 15-9
|
||
PS_DRIVES
|
||
|
||
PSEL class method, 15-10
|
||
PS_GET_FILE
|
||
|
||
PSEL class method, 15-8
|
||
PS_GETTAG
|
||
|
||
PSEL class method, 15-10
|
||
PS_NEW_LIST
|
||
|
||
PSEL class method deferred, 15-11
|
||
PS_ORDER
|
||
|
||
PSEL class method, 15-10
|
||
PS_SELECT_DIRENTRY
|
||
|
||
PSEL class method, 15-9
|
||
|
||
|
||
viii
|
||
|
||
|
||
PS_SENSE_FILENAME
|
||
PSEL class method, 15-9
|
||
PS_SET_PATH
|
||
PSEL class method, 15-9
|
||
PS_SETTAG
|
||
PSEL class method, 15-10
|
||
PSEL class
|
||
AO_ABRUN method, 15-7
|
||
AO_CANCEL method, 15-7
|
||
AO_INIT method, 15-7
|
||
FS_DIRNAME method, 15-8
|
||
FS_FILENAME method, 15-8
|
||
FS_FSCAN_END method, 15-8
|
||
methods deferred, 15-11
|
||
methods, 15-7
|
||
oop, 15-4
|
||
PS_ASCEND_PATH method, 15-9
|
||
PS_DESCEND_PATH method, 15-9
|
||
PS_DRIVES method, 15-10
|
||
PS_GET_FILE method, 15-8
|
||
PS_GETTAG method, 15-10
|
||
PS_NEW_LIST deferred method, 15-11
|
||
PS_ORDER method, 15-10
|
||
PS_SELECT_DIRENTRY method, 15-9
|
||
PS_SENSE_FILENAME method, 15-9
|
||
PS_SET_PATH method, 15-9
|
||
PS_SETTAG method, 15-10
|
||
pselvar
|
||
file lists, 15-1
|
||
PSELVAR class
|
||
methods, 15-3
|
||
oop, 15-2
|
||
VA_TEST method, 15-3
|
||
REM
|
||
filing system node, 14-8
|
||
RESOURCE FILES
|
||
class, 7-1
|
||
ROM
|
||
filing system node, 14-8, 17-1
|
||
ROOT class
|
||
DESTROY method, 2-2
|
||
methods, 2-2
|
||
oop superclass, 2-1
|
||
RS_INIT
|
||
RSCFILE class method, 7-2
|
||
RS_READ
|
||
RSCFILE class method, 7-2
|
||
RS_READ_BUF
|
||
RSCFILE class method, 7-2
|
||
RSCFILE class
|
||
DESTROY method, 7-2
|
||
methods, 7-2
|
||
RS_INIT method, 7-2
|
||
RS_READ method, 7-2
|
||
RS_READ_BUF method, 7-2
|
||
SB_ALLOCSEG
|
||
SGBUFEF class method, 4-4
|
||
SB_BACKPOINT
|
||
SGBUF class method, 4-4
|
||
SB_COMPRESS
|
||
SGBUF class method, 4-4
|
||
SB_COUNT
|
||
SGBUF class method, 4-4
|
||
|
||
|
||
SB_DELETE
|
||
|
||
SGBUF class method, 4-3
|
||
SB_EXTRACT
|
||
|
||
SGBUF class method, 4-4
|
||
SB_INIT
|
||
|
||
SGBUF class method, 4-2
|
||
SB_INSERT
|
||
|
||
SGBUF class method, 4-3
|
||
SB_POINT
|
||
|
||
SGBUF class method, 4-3
|
||
SCAN class
|
||
|
||
file scan local, 17-1
|
||
|
||
oop, 17-1
|
||
SERFILE class
|
||
|
||
methods, 8-13
|
||
|
||
oop class, 8-11
|
||
|
||
TD_RESET method, 8-13
|
||
|
||
TD_SENSE_ITEM method, 8-14
|
||
|
||
TD_SET_FILE method, 8-13
|
||
|
||
TD_SET_ITEM method, 8-13
|
||
serial port
|
||
|
||
parameter .trm file, 8-11
|
||
SERVER class
|
||
|
||
DESTROY method, 19-5
|
||
|
||
methods deferredoop, 19-6
|
||
|
||
methods, 19-5
|
||
|
||
services, 19-4
|
||
|
||
SV_ABRUN method, 19-5
|
||
|
||
SV_INIT method, 19-5
|
||
|
||
SV_RUN deferred method, 19-6
|
||
SGBUF class
|
||
|
||
DESTROY method, 4-2
|
||
|
||
methods, 4-2
|
||
|
||
oop class, 4-1
|
||
|
||
SB_ALLOCSEG method, 4-4
|
||
|
||
SB_BACKPOINT method, 4-4
|
||
|
||
SB_COMPRESS method, 4-4
|
||
|
||
SB_COUNT method, 4-4
|
||
|
||
SB_DELETE method, 4-3
|
||
|
||
SB_EXTRACT method, 4-4
|
||
|
||
SB_INIT method, 4-2
|
||
|
||
SB_INSERT method, 4-3
|
||
|
||
SB_POINT method, 4-3
|
||
sub-class
|
||
|
||
FCASY, 14-1
|
||
|
||
FCSYNC, 14-1
|
||
|
||
FMFMT, 16-1
|
||
|
||
FMMK, 16-1
|
||
|
||
FMSCAN, 16-1
|
||
|
||
FMSRC, 16-1
|
||
|
||
FMTARG, 16-1
|
||
|
||
FNODE, 14-1
|
||
|
||
FSCAN, 14-1
|
||
SV_ABRUN
|
||
|
||
SERVER class method, 19-5
|
||
SV_INIT
|
||
|
||
LINKSV class method, 20-5
|
||
|
||
SERVER class method, 19-5
|
||
SV_RUN
|
||
|
||
LINKSV class method, 20-5
|
||
|
||
SERVER class method deferred, 19-6
|
||
SY_EXEC_OPEN
|
||
|
||
SYSTEM class method, 18-3
|
||
|
||
|
||
INDEX
|
||
|
||
|
||
SY_ICON_POS
|
||
|
||
SYSTEM class method, 18-2
|
||
SY_INIT
|
||
|
||
SYSTEM class method, 18-2
|
||
SY_LINK_PASTE
|
||
|
||
SYSTEM class method, 18-3
|
||
SY_LINK_SERVER
|
||
|
||
SYSTEM class method, 18-3
|
||
SYSTEM class
|
||
|
||
methods, 18-2
|
||
|
||
services, 18-1
|
||
|
||
SY_EXEC_OPEN method, 18-3
|
||
|
||
SY_ICON_POS method, 18-2
|
||
|
||
SY_INIT method, 18-2
|
||
|
||
SY_LINK_PASTE method, 18-3
|
||
|
||
SY_LINK_SERVER method, 18-3
|
||
SYSTEM SERVICES
|
||
|
||
class, 18-1
|
||
TD_CHANGED
|
||
|
||
TLVDATA class method, 8-9
|
||
TD_LOAD_ITEM
|
||
|
||
TLVDATA class method, 8-10
|
||
TD_OPEN
|
||
|
||
TLVDATA class method, 8-9
|
||
TD_RESET
|
||
|
||
SERFILE class method, 8-13
|
||
|
||
TLVDATA class method, 8-10
|
||
TD_SAVE
|
||
|
||
TLVDATA class method, 8-9
|
||
TD_SAVE_ITEM
|
||
|
||
TLVDATA class method, 8-10
|
||
TD_SENSE_ITEM
|
||
|
||
SERFILE class method, 8-14
|
||
|
||
TLVDATA class method deferred, 8-10
|
||
TD_SET_FILE
|
||
|
||
SERFILE class method, 8-13
|
||
|
||
TLVDATA class method deferred, 8-10
|
||
TD_SET_ITEM
|
||
|
||
SERFILE class method, 8-13
|
||
|
||
TLVDATA class method deferred, 8-10
|
||
TIME class
|
||
|
||
methods, 3-3
|
||
|
||
oop class, 3-1
|
||
|
||
TO_ADD_DAYS method, 3-5
|
||
|
||
TO_ADD_MONTHS method, 3-5
|
||
|
||
TO_ADD_SECS method, 3-4
|
||
|
||
TO_ADD_YEARS method, 3-5
|
||
|
||
TO_GET_SYSDAT method, 3-7
|
||
|
||
TO_SENSE method, 3-4
|
||
|
||
TO_SENSE_FORMAT method, 3-6
|
||
|
||
TO_SET method, 3-3
|
||
|
||
TO_SET_FORMAT method, 3-6
|
||
TIMER class
|
||
|
||
active object, 13-1
|
||
|
||
AO_INIT method, 13-2
|
||
|
||
AO_QUEUE method, 13-2
|
||
|
||
methods, 13-2
|
||
|
||
oop, 13-1, 13-2
|
||
|
||
TM_QABSOLUTE method, 13-3
|
||
TLVDATA class
|
||
|
||
methods deferred, 8-10
|
||
|
||
methods, 8-9
|
||
|
||
oop class, 8-8
|
||
|
||
TD_CHANGED method, 8-9
|
||
|
||
|
||
OLIB REFERENCE
|
||
|
||
|
||
TD_LOAD_ITEM method, 8-10
|
||
TD_OPEN method, 8-9
|
||
TD_RESET method, 8-10
|
||
TD_SAVE method, 8-9
|
||
TD_SAVE_ITEM method, 8-10
|
||
|
||
|
||
TD_SENSE_ITEM method deferred, 8-10
|
||
|
||
|
||
TD_SET_FILE method deferred, 8-10
|
||
|
||
TD_SET_ITEM method deferred, 8-10
|
||
TLVFILE class
|
||
|
||
FI_OPEN method, 8-6
|
||
|
||
FL_COUNT method, 8-6
|
||
|
||
FL_DELREC method, 8-7
|
||
|
||
FL_READ_BY_TYPE method, 8-7
|
||
|
||
FL_REPLACE method, 8-7
|
||
|
||
FL_REWIND method, 8-6
|
||
|
||
FL_SENSE_REC method, 8-7
|
||
|
||
FL_SET_REC method, 8-6
|
||
|
||
FL_WRITE_REC method, 8-6
|
||
|
||
methods, 8-6
|
||
|
||
oop class, 8-4
|
||
TM_QABSOLUTE
|
||
|
||
TIMER class method, 13-3
|
||
TO_ADD_DAYS
|
||
|
||
TIME class method, 3-5
|
||
TO_ADD_MONTHS
|
||
|
||
TIME class method, 3-5
|
||
TO_ADD_SECS
|
||
|
||
TIME class method, 3-4
|
||
TO_ADD_YEARS
|
||
|
||
TIME class method, 3-5
|
||
TO_GET_SYSDAT
|
||
|
||
TIME class method, 3-7
|
||
TO_SENSE
|
||
|
||
TIME class method, 3-4
|
||
TO_SENSE_FORMAT
|
||
|
||
TIME class method, 3-6
|
||
TO_SET
|
||
|
||
TIME class method, 3-3
|
||
TO_SET_FORMAT
|
||
|
||
TIME class method, 3-6
|
||
type-length-value
|
||
|
||
files, 8-4
|
||
VA_APPEND
|
||
|
||
VAROOT class method, 5-4
|
||
VA_CAPACITY
|
||
|
||
VAFLAT class method, 5-15
|
||
|
||
VAROOT class method deferred, 5-8
|
||
|
||
VASEG class method, 5-17
|
||
|
||
VASTR class method, 5-13
|
||
VA_COMPARE
|
||
|
||
VAROOT class method, 5-5
|
||
VA_COMPRESS
|
||
|
||
VAFLAT class method, 5-15
|
||
|
||
VAROOT class method deferred, 5-8
|
||
|
||
VASEG class method, 5-17
|
||
|
||
VASTR class method, 5-13
|
||
VA_COPY
|
||
|
||
VAFIX class method, 5-10
|
||
|
||
VAROOT class method deferred, 5-7
|
||
|
||
VASTR class method, 5-14
|
||
|
||
VAXVAR class method, 5-21
|
||
VA_COUNT
|
||
|
||
VAROOT class method, 5-4
|
||
|
||
|
||
VA_DELETE
|
||
|
||
VAROOT class method, 5-5
|
||
VA_DELETEM
|
||
|
||
VAFLAT class method, 5-15
|
||
|
||
VAROOT class method deferred, 5-8
|
||
|
||
VASEG class method, 5-17
|
||
|
||
VASTR class method, 5-13
|
||
|
||
VAXVAR class method, 5-20
|
||
VA_FINDISQ
|
||
|
||
VAROOT class method, 5-6
|
||
VA_INIT
|
||
|
||
VAFLAT class method, 5-15
|
||
|
||
VAROOT class method deferred, 5-8
|
||
|
||
VASEG class method, 5-17
|
||
|
||
VASTR class method, 5-12
|
||
|
||
VAXVAR class method, 5-20
|
||
VA_INSERT
|
||
|
||
VAROOT class method, 5-4
|
||
VA_INSERTISQ
|
||
|
||
VAROOT class method, 5-6
|
||
VA_INSERTM
|
||
|
||
VAFLAT class method, 5-15
|
||
|
||
VAROOT class method deferred, 5-8
|
||
|
||
VASEG class method, 5-18
|
||
|
||
VASTR class method, 5-13
|
||
|
||
VAXVAR class method, 5-20
|
||
VA_KEY
|
||
|
||
VAROOT class method, 5-5
|
||
VA_PBUF
|
||
|
||
VAFLAT class method, 5-16
|
||
|
||
VAROOT class method deferred, 5-9
|
||
|
||
VASEG class method, 5-18
|
||
|
||
VASTR class method, 5-14
|
||
|
||
VAXVAR class method, 5-21
|
||
VA_PREC
|
||
|
||
VAFLAT class method, 5-16
|
||
|
||
VAROOT class method deferred, 5-9
|
||
|
||
VASEG class method, 5-18
|
||
|
||
VASTR class method, 5-13
|
||
VA_RECLEN
|
||
|
||
VAFIX class method, 5-10
|
||
|
||
VAROOT class method deferred, 5-7
|
||
|
||
VASTR class method, 5-13
|
||
|
||
VAXVAR class method, 5-21
|
||
VA_REPLACE
|
||
|
||
VAFIX class method, 5-10
|
||
|
||
VAROOT class method, 5-7
|
||
|
||
VAXVAR class method, 5-21
|
||
VA_RESET
|
||
|
||
VAROOT class method, 5-7
|
||
VA_SEARCH
|
||
|
||
VAROOT class method, 5-6
|
||
VA_SORT
|
||
|
||
VAROOT class method, 5-6
|
||
VA_SWAP
|
||
|
||
VAFIX class method, 5-10
|
||
|
||
VAROOT class method deferred, 5-7
|
||
VA_TEST
|
||
|
||
PSELVAR class method, 15-3
|
||
|
||
VAROOT class method, 5-5
|
||
|
||
VAXVAR class method, 5-20
|
||
VAFIX class
|
||
|
||
methods, 5-10
|
||
|
||
oop class, 5-9
|
||
|
||
|
||
INDEX
|
||
|
||
|
||
VA_COPY method, 5-10 VA_PREC method, 5-13
|
||
VA_RECLEN method, 5-10 VA_RECLEN method, 5-13
|
||
VA_REPLACE method, 5-10 VAXVAR class
|
||
VA_SWAP method, 5-10 methods, 5-20
|
||
|
||
VAFLAT class oop class, 5-18
|
||
methods, 5-15 VA_COPY method, 5-21
|
||
oop class, 5-14 VA_DELETEM method, 5-20
|
||
VA_CAPACITY method, 5-15 VA_INIT method, 5-20
|
||
VA_COMPRESS method, 5-15 VA_INSERTM method, 5-20
|
||
VA_DELETEM method, 5-15 VA_PBUF method, 5-21
|
||
VA_INIT method, 5-15 VA_RECLEN method, 5-21
|
||
VA_INSERTM method, 5-15 VA_REPLACE method, 5-21
|
||
VA_PBUF method, 5-16 VA_TEST method, 5-20
|
||
VA_PREC method, 5-16 VAXVARS class
|
||
|
||
VARIABLE ARRAY methods, 5-22
|
||
classes, 5-1 oop class, 5-21
|
||
|
||
VAROOT class
|
||
|
||
|
||
DESTROY method, 5-4
|
||
methods deferred, 5-7
|
||
methods, 5-4
|
||
oop class, 5-3
|
||
VA_APPEND method, 5-4
|
||
VA_CAPACITY method deferred, 5-8
|
||
VA_COMPARE method, 5-5
|
||
VA_COMPRESS method deferred, 5-8
|
||
VA_COPY method deferred, 5-7
|
||
VA_COUNT method, 5-4
|
||
VA_DELETE method, 5-5
|
||
VA_DELETEM method deferred, 5-8
|
||
VA_FINDISQ method, 5-6
|
||
VA_INIT method deferred, 5-8
|
||
VA_INSERT method, 5-4
|
||
VA_INSERTISQ method, 5-6
|
||
VA_INSERTM method deferred, 5-8
|
||
VA_KEY method, 5-5
|
||
VA_PBUF method deferred, 5-9
|
||
VA_PREC method deferred, 5-9
|
||
VA_RECLEN method deferred, 5-7
|
||
VA_REPLACE method, 5-7
|
||
VA_RESET method, 5-7
|
||
VA_SEARCH method, 5-6
|
||
VA_SORT method, 5-6
|
||
VA_SWAP method deferred, 5-7
|
||
VA_TEST method, 5-5
|
||
|
||
VASEG class
|
||
methods, 5-17
|
||
oop class, 5-16
|
||
VA_CAPACITY method, 5-17
|
||
VA_COMPRESS method, 5-17
|
||
VA_DELETEM method, 5-17
|
||
VA_INIT method, 5-17
|
||
VA_INSERTM method, 5-18
|
||
VA_PBUF method, 5-18
|
||
VA_PREC method, 5-18
|
||
|
||
VASTR class
|
||
methods, 5-12
|
||
oop class, 5-11
|
||
VA_CAPACITY method, 5-13
|
||
VA_COMPRESS method, 5-13
|
||
VA_COPY method, 5-14
|
||
VA_DELETEM method, 5-13
|
||
VA_INIT method, 5-12
|
||
VA_INSERTM method, 5-13
|
||
VA_PBUF method, 5-14
|
||
|
||
|