hidlcomp.cpp 251 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335
  1. /*##############################################################################
  2. HPCC SYSTEMS software Copyright (C) 2012 HPCC Systems®.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. ############################################################################## */
  13. #pragma warning(disable:4786)
  14. #include "platform.h"
  15. #include "hidl_utils.hpp"
  16. #include "hidlcomp.h"
  17. #include "AccessMapGenerator.hpp"
  18. #include <algorithm>
  19. #include <list>
  20. #include <map>
  21. #include <set>
  22. #include <string>
  23. //-------------------------------------------------------------------------------------------------------------
  24. inline bool strieq(const char* s,const char* t) { return stricmp(s,t)==0; }
  25. //-------------------------------------------------------------------------------------------------------------
  26. #define HIDL "HIDL"
  27. extern FILE *yyin;
  28. extern int yyparse();
  29. extern HIDLcompiler * hcp;
  30. // --- globals -----
  31. bool isSCM = true;
  32. bool isESP = false;
  33. bool isESPng = false;
  34. StrBuffer clarion;
  35. char srcFileExt[4];
  36. int gOutfile;
  37. //-------------------------------------------------------------------------------------------------------------
  38. // Utility struct and function
  39. char* getFieldName(const char* name)
  40. {
  41. char *uname=strdup(name);
  42. *uname=upperchar(*uname);
  43. return uname;
  44. }
  45. static const char* getTypeKindName(type_kind kind)
  46. {
  47. switch (kind)
  48. {
  49. case TK_null: return "TK_null";
  50. case TK_CHAR: return "TK_CHAR";
  51. case TK_UNSIGNEDCHAR: return "TK_UNSIGNEDCHAR";
  52. case TK_BYTE: return "TK_BYTE";
  53. case TK_BOOL: return "TK_BOOL";
  54. case TK_SHORT: return "TK_SHORT";
  55. case TK_UNSIGNEDSHORT: return "TK_UNSIGNEDSHORT";
  56. case TK_INT: return "TK_INT";
  57. case TK_UNSIGNED: return "TK_UNSIGNED";
  58. case TK_LONG: return "TK_LONG";
  59. case TK_UNSIGNEDLONG: return "TK_UNSIGNEDLONG";
  60. case TK_LONGLONG: return "TK_LONGLONG";
  61. case TK_UNSIGNEDLONGLONG: return "TK_UNSIGNEDLONGLONG";
  62. case TK_DOUBLE: return "TK_DOUBLE";
  63. case TK_FLOAT: return "TK_FLOAT";
  64. case TK_STRUCT: return "TK_STRUCT";
  65. case TK_ENUM: return "TK_ENUM";
  66. case TK_VOID: return "TK_VOID";
  67. case TK_ESPSTRUCT: return "TK_ESPSTRUCT";
  68. case TK_ESPENUM: return "TK_ESPENUM";
  69. default: return "<unknown kind>";
  70. }
  71. };
  72. const char *type_name[] =
  73. {
  74. "??",
  75. "char",
  76. "unsigned char",
  77. "byte",
  78. "bool",
  79. "short",
  80. "unsigned short",
  81. "int",
  82. "unsigned",
  83. "long",
  84. "unsigned long",
  85. "__int64",
  86. "unsigned __int64",
  87. "double",
  88. "float",
  89. "", // STRUCT
  90. "", // ENUM
  91. "void",
  92. "??", // ESPSTRUCT
  93. "??" // ESPENUM
  94. };
  95. const char *clarion_type_name[] =
  96. {
  97. "??",
  98. "BYTE",
  99. "BYTE",
  100. "BYTE",
  101. "CBOOL",
  102. "SHORT",
  103. "USHORT",
  104. "LONG",
  105. "ULONG",
  106. "LONG",
  107. "ULONG",
  108. "LONGLONG",
  109. "ULONGLONG",
  110. "REAL",
  111. "SREAL",
  112. "",
  113. "",
  114. "BYTE",
  115. "??",
  116. "??"
  117. };
  118. const int type_size[] =
  119. {
  120. 0, // tk_null
  121. 1, // TK_CHAR
  122. 1, // TK_UCHAR
  123. 1, // BYTE
  124. 1, // BOOL
  125. 2, // SHORT
  126. 2, // USHORT
  127. 4, // INT
  128. 4, // UNSIGNED
  129. 4, // LONG
  130. 4, // ULONG
  131. 8, // LONGLONG
  132. 8, // ULONGLONG
  133. 8, // DOUBLE
  134. 4, // FLOAT
  135. 4, // STRUCT
  136. 4, // ENUM
  137. 0, // void
  138. 1, // ESP_STRUCT
  139. 1 // ESP_ENUM
  140. };
  141. static const char *xlattable[] =
  142. {
  143. "abs","_abs",
  144. "add","_add",
  145. "address","_address",
  146. "age","_age",
  147. "any","_any",
  148. "append","_append",
  149. "at","_at",
  150. "band","_band",
  151. "bfloat4","_bfloat4",
  152. "bfloat8","_bfloat8",
  153. "binary","_binary",
  154. "bind","_bind",
  155. "blob","_blob",
  156. "bor","_bor",
  157. "bshift","_bshift",
  158. "bxor","_bxor",
  159. "byte","_byte",
  160. "chr","_chr",
  161. "clear","_clear",
  162. "column","_column",
  163. "create","_create",
  164. "decimal","_decimal",
  165. "deformat","_deformat",
  166. "device","_device",
  167. "dim","_dim",
  168. "dispose","_dispose",
  169. "dock","_dock",
  170. "docked","_docked",
  171. "dup","_dup",
  172. "encrypt","_encrypt",
  173. "entry","_entry",
  174. "equate","_equate",
  175. "errorcode","_errorcode",
  176. "format","_format",
  177. "get","_get",
  178. "hlp","_hlp",
  179. "icon","_icon",
  180. "imm","_imm",
  181. "in","_in",
  182. "index","_index",
  183. "inlist","_inlist",
  184. "inrange","_inrange",
  185. "ins","_ins",
  186. "int","_int",
  187. "key","_key",
  188. "length","_length",
  189. "like","_like",
  190. "logout","_logout",
  191. "long","_long",
  192. "maximum","_maximum",
  193. "memo","_memo",
  194. "nocase","_nocase",
  195. "omitted","_omitted",
  196. "opt","_opt",
  197. "out","_out",
  198. "over","_over",
  199. "ovr","_ovr",
  200. "owner","_owner",
  201. "page","_page",
  202. "pageno","_pageno",
  203. "pdecimal","_pdecimal",
  204. "peek","_peek",
  205. "poke","_poke",
  206. "pre","_pre",
  207. "press","_press",
  208. "print","_print",
  209. "project","_project",
  210. "put","_put",
  211. "range","_range",
  212. "real","_real",
  213. "reclaim","_reclaim",
  214. "req","_req",
  215. "round","_round",
  216. "scroll","_scroll",
  217. "short","_short",
  218. "size","_size",
  219. "sort","_sort",
  220. "step","_step",
  221. "string","_string",
  222. "text","_text",
  223. "upr","_upr",
  224. "use","_use",
  225. "val","_val",
  226. "width","_width",
  227. NULL,NULL
  228. };
  229. static const char *xlat(const char *from)
  230. {
  231. for (unsigned i=0;xlattable[i];i+=2) {
  232. if (stricmp(from,xlattable[i])==0)
  233. return xlattable[i+1];
  234. }
  235. return from;
  236. }
  237. bool toClaInterface(char * dest, const char * src)
  238. {
  239. if(*src == 'I' && strlen(src) > 1)
  240. {
  241. strcpy(dest, "cpp");
  242. strcpy(dest + 3, src + 1);
  243. return true;
  244. }
  245. strcpy(dest, src);
  246. return false;
  247. }
  248. #define ForEachParam(pr,pa,flagsset,flagsclear) for (pa=pr->params;pa;pa=pa->next) \
  249. if (((pa->flags&(flagsset))==(flagsset))&((pa->flags&(flagsclear))==0))
  250. #define INDIRECTSIZE(p) ((p->flags&(PF_PTR|PF_REF))==(PF_PTR|PF_REF))
  251. void indent(int indents)
  252. {
  253. for (int i=0;i<indents; i++)
  254. out("\t",1);
  255. }
  256. void out(const char *s,size_t l)
  257. {
  258. ssize_t written = write(gOutfile,s,(unsigned)l);
  259. if (written < 0)
  260. throw "Error while writing out";
  261. if (written != l)
  262. throw "Truncated write";
  263. }
  264. void outs(const char *s)
  265. {
  266. out(s,strlen(s));
  267. }
  268. void outs(int indents, const char *s)
  269. {
  270. indent(indents);
  271. out(s,strlen(s));
  272. }
  273. static void voutf(const char* fmt,va_list args) __attribute__((format(printf,1,0)));
  274. void voutf(const char* fmt,va_list args)
  275. {
  276. const int BUF_LEN = 0x4000;
  277. static char buf[BUF_LEN+1];
  278. // Better to use StringBuffer.valist_appendf, but unfortunately, project dependencies
  279. // disallow us to use StringBuffer (defined in jlib).
  280. if (_vsnprintf(buf, BUF_LEN, fmt, args)<0)
  281. fprintf(stderr,"Warning: outf() gets too many long buffer (>%d)", BUF_LEN);
  282. va_end(args);
  283. outs(buf);
  284. }
  285. void outf(const char *fmt, ...)
  286. {
  287. va_list args;
  288. va_start(args, fmt);
  289. voutf(fmt,args);
  290. }
  291. void outf(int indents, const char *fmt, ...)
  292. {
  293. indent(indents);
  294. va_list args;
  295. va_start(args, fmt);
  296. voutf(fmt,args);
  297. }
  298. // ------------------------------------
  299. // "auto" indenting
  300. int gIndent = 0;
  301. void indentReset(int indent=0) { gIndent = indent; }
  302. void indentInc(int inc) { gIndent += inc; }
  303. void indentOuts(const char* s)
  304. {
  305. indent(gIndent);
  306. out(s,strlen(s));
  307. }
  308. void indentOuts(int inc, const char* s)
  309. {
  310. gIndent += inc;
  311. indentOuts(s);
  312. }
  313. void indentOuts1(int inc, const char* s)
  314. {
  315. indent(gIndent+inc);
  316. out(s,strlen(s));
  317. }
  318. void indentOutf(const char* fmt,...) __attribute__((format(printf,1,2)));
  319. void indentOutf(const char* fmt, ...)
  320. {
  321. indent(gIndent);
  322. va_list args;
  323. va_start(args, fmt);
  324. voutf(fmt,args);
  325. }
  326. void indentOutf(int inc, const char* fmt,...) __attribute__((format(printf,2,3)));
  327. void indentOutf(int inc, const char* fmt, ...)
  328. {
  329. gIndent += inc;
  330. indent(gIndent);
  331. va_list args;
  332. va_start(args, fmt);
  333. voutf(fmt,args);
  334. }
  335. void indentOutf1(int inc, const char* fmt,...) __attribute__((format(printf,2,3)));
  336. void indentOutf1(int inc, const char* fmt, ...)
  337. {
  338. indent(gIndent+inc);
  339. va_list args;
  340. va_start(args, fmt);
  341. voutf(fmt,args);
  342. }
  343. //-------------------------------------------------------------------------------------------------------------
  344. // class LayoutInfo
  345. LayoutInfo::LayoutInfo()
  346. {
  347. size = 0;
  348. count = 0;
  349. next = NULL;
  350. }
  351. LayoutInfo::~LayoutInfo()
  352. {
  353. delete next;
  354. }
  355. //-------------------------------------------------------------------------------------------------------------
  356. // class ParamInfo
  357. ParamInfo::ParamInfo()
  358. {
  359. name = NULL;
  360. templ = NULL;
  361. typname = NULL;
  362. size = NULL;
  363. flags = 0;
  364. next = NULL;
  365. kind = TK_null;
  366. sizebytes = NULL;
  367. layouts = NULL;
  368. tags = NULL;
  369. xsdtype = NULL;
  370. m_arrayImplType = NULL;
  371. }
  372. ParamInfo::~ParamInfo()
  373. {
  374. if (name)
  375. free(name);
  376. if (typname)
  377. free(typname);
  378. if (size)
  379. free(size);
  380. if (sizebytes)
  381. free(sizebytes);
  382. if (templ)
  383. free(templ);
  384. if (xsdtype)
  385. free(xsdtype);
  386. if (m_arrayImplType)
  387. delete m_arrayImplType;
  388. delete tags;
  389. delete layouts;
  390. delete next;
  391. }
  392. char * ParamInfo::bytesize(int deref)
  393. {
  394. if (!size)
  395. return NULL;
  396. if (sizebytes)
  397. return sizebytes;
  398. char str[1024];
  399. if (type_size[kind]==1)
  400. {
  401. if (deref)
  402. {
  403. strcpy(str,"*");
  404. strcat(str,size);
  405. sizebytes = strdup(str);
  406. return sizebytes;
  407. }
  408. else
  409. return size;
  410. }
  411. strcpy(str,"sizeof(");
  412. if (kind==TK_STRUCT)
  413. strcat(str,typname);
  414. else
  415. strcat(str,type_name[kind]);
  416. strcat(str,")*(");
  417. if (deref)
  418. strcat(str,"*");
  419. strcat(str,size);
  420. strcat(str,")");
  421. sizebytes = strdup(str);
  422. return sizebytes;
  423. }
  424. bool ParamInfo::simpleneedsswap()
  425. {
  426. switch(kind) {
  427. case TK_SHORT:
  428. case TK_UNSIGNEDSHORT:
  429. case TK_INT:
  430. case TK_UNSIGNED:
  431. case TK_LONG:
  432. case TK_UNSIGNEDLONG:
  433. case TK_LONGLONG:
  434. case TK_UNSIGNEDLONGLONG:
  435. return true;
  436. default:
  437. return false;
  438. }
  439. }
  440. void ParamInfo::cat_type(char *s,int deref,int var)
  441. {
  442. if ((flags&PF_CONST)&&!var)
  443. strcat(s,"const ");
  444. if (typname)
  445. strcat(s,typname);
  446. else {
  447. if (kind!=TK_null)
  448. strcat(s,type_name[kind]);
  449. else
  450. strcat(s,"string"); // TODO: why this happens?
  451. }
  452. if (!deref) {
  453. if (flags&PF_PTR)
  454. strcat(s," *");
  455. if (flags&PF_REF)
  456. strcat(s," &");
  457. }
  458. }
  459. clarion_special_type_enum ParamInfo::clarion_special_type()
  460. {
  461. if ((type_size[kind]==1)&&((flags&(PF_PTR|PF_REF))==PF_PTR)) {
  462. if ((flags&PF_CONST)==0)
  463. return cte_cstr;
  464. return cte_constcstr;
  465. }
  466. else if ((flags&(PF_PTR|PF_REF))==(PF_PTR|PF_REF)) { // no support - convert to long
  467. return cte_longref;
  468. }
  469. return cte_normal;
  470. }
  471. void ParamInfo::out_parameter(const char * pfx, int forclarion)
  472. {
  473. if (forclarion && (clarion_special_type()==cte_cstr))
  474. outs("int, ");
  475. out_type();
  476. outf(" %s%s",pfx,name);
  477. }
  478. void ParamInfo::out_type(int deref,int var)
  479. {
  480. char s[256];
  481. s[0] = 0;
  482. cat_type(s,deref,var);
  483. outs(s);
  484. }
  485. void ParamInfo::typesizeacc(char *accstr,size_t &acc)
  486. {
  487. if ((kind==TK_STRUCT)||(flags&(PF_PTR|PF_REF))) {
  488. acc = (acc+3)&~3;
  489. if (*accstr)
  490. strcat(accstr,"+");
  491. strcat(accstr,"sizeof(");
  492. cat_type(accstr);
  493. strcat(accstr,")");
  494. }
  495. else {
  496. size_t sz=type_size[kind];
  497. if (sz==2)
  498. acc = (acc+1)&~1;
  499. else if (sz>=4)
  500. acc = (acc+3)&~3;
  501. acc += type_size[kind];
  502. }
  503. }
  504. size_t ParamInfo::typesizealign(size_t &ofs)
  505. {
  506. size_t ret=0;
  507. if ((kind==TK_STRUCT)||(flags&(PF_PTR|PF_REF))) {
  508. if (ofs) {
  509. ret = 4-ofs;
  510. ofs = 0;
  511. }
  512. }
  513. else {
  514. size_t sz=type_size[kind];
  515. if (sz==1) {
  516. ret = 0;
  517. ofs = (ofs+1)%4;
  518. }
  519. else if (sz==2) {
  520. ret = (ofs&1);
  521. ofs = (ofs+ret+2)%4;
  522. }
  523. else {
  524. if (ofs) {
  525. ret = 4-ofs;
  526. ofs = 0;
  527. }
  528. }
  529. }
  530. return ret;
  531. }
  532. void ParamInfo::write_body_struct_elem(int ref)
  533. {
  534. outs("\t");
  535. out_type(ref,1);
  536. if (ref&&(flags&(PF_REF|PF_PTR)))
  537. {
  538. outs(" *");
  539. if ((flags&(PF_REF|PF_PTR))==(PF_REF|PF_PTR))
  540. {
  541. outs(" *");
  542. }
  543. }
  544. outf(" %s;\n",name);
  545. }
  546. void ParamInfo::out_clarion_parameter()
  547. {
  548. out_clarion_type(false);
  549. if(!typname || strcmp(typname, "__int64") != 0) outs(" ");
  550. if (clarion_special_type()==cte_longref)
  551. outs("REF_");
  552. if (name)
  553. outs(name);
  554. else
  555. outs("???");
  556. }
  557. void ParamInfo::out_clarion_type(bool ret)
  558. {
  559. clarion_special_type_enum cte = clarion_special_type();
  560. bool isInt64 = (typname && strcmp(typname, "__int64") == 0);
  561. if (!isInt64 && ((flags&PF_REF)||((flags&PF_PTR)&&(cte==cte_normal)))) {
  562. outs("*");
  563. }
  564. if (cte==cte_longref) {
  565. outs("LONG");
  566. }
  567. else if (cte==cte_cstr) {
  568. outs("*CSTRING");
  569. }
  570. else if (cte==cte_constcstr) {
  571. if (ret)
  572. outs("*CSTRING");
  573. else
  574. outs("CONST *CSTRING");
  575. }
  576. else if (typname) {
  577. static char _typname[256];
  578. if(isInt64) {
  579. if(ret) {
  580. strcpy(_typname, "__int64"); // __int64 return type unsupported defaulting to ulong for now.
  581. }
  582. else if((flags & PF_REF) || (flags & PF_PTR)) {
  583. strcpy(_typname, "LONG ");
  584. }
  585. else {
  586. strcpy(_typname, "LONG hi");
  587. strcat(_typname, name);
  588. strcat(_typname, ", LONG lo");
  589. }
  590. }
  591. else if(!toClaInterface(_typname, typname)){
  592. xlat(_typname);
  593. }
  594. outs(_typname);
  595. }
  596. else {
  597. outs(clarion_type_name[kind]);
  598. }
  599. }
  600. void ParamInfo::write_param_convert(int deref)
  601. {
  602. outs("(");
  603. out_type(1,1);
  604. if (flags&(PF_REF|PF_PTR)) {
  605. if (!deref)
  606. outs(" *");
  607. if ((flags&(PF_REF|PF_PTR))==(PF_REF|PF_PTR)) {
  608. outs(" *");
  609. }
  610. }
  611. outs(")");
  612. }
  613. bool ParamInfo::hasMapInfo()
  614. {
  615. if (hasMetaVerInfo("min_ver") || hasMetaVerInfo("max_ver") || hasMetaVerInfo("depr_ver"))
  616. return true;
  617. if (getMetaString("optional", NULL))
  618. return true;
  619. return false;
  620. }
  621. static esp_xlate_info esp_xlate_table[]=
  622. {
  623. //meta type xsd type implementation array impl access type type_kind flags method
  624. //------------------ --------------- -------------- -------------- -------------- ----------- ------------ ----------
  625. // {"string", "string", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  626. {"string", "string", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  627. {"StringBuffer", "string", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  628. // {"hexBinary", "base64Binary", "MemoryBuffer", "???", "unsigned char *", TK_UNSIGNEDCHAR, (PF_PTR), EAM_jmbuf},
  629. {"binary", "base64Binary", "MemoryBuffer", "???", "const MemoryBuffer &", TK_STRUCT, (PF_REF), EAM_jmbin},
  630. {"bool", "boolean", "bool", "BoolArray", "bool", TK_BOOL, 0, EAM_basic},
  631. {"boolean", "boolean", "bool", "BoolArray", "bool", TK_BOOL, 0, EAM_basic},
  632. {"decimal", "decimal", "float", "???", "float", TK_FLOAT, 0, EAM_basic},
  633. {"float", "float", "float", "FloatArray", "float", TK_FLOAT, 0, EAM_basic},
  634. {"double", "double", "double", "DoubleArray", "double", TK_DOUBLE, 0, EAM_basic},
  635. {"integer", "integer", "int", "???", "int", TK_INT, 0, EAM_basic},
  636. {"int64", "long", "__int64", "Int64Array", "__int64", TK_LONGLONG, 0, EAM_basic},
  637. {"long", "long", "long", "Int64Array", "__int64", TK_LONG, 0, EAM_basic},
  638. {"int", "int", "int", "IntArray", "int", TK_INT, 0, EAM_basic},
  639. {"short", "short", "short", "ShortArray", "short", TK_SHORT, 0, EAM_basic},
  640. {"nonPositiveInteger", "nonPositiveInteger", "int", "???", "int", TK_INT, 0, EAM_basic},
  641. {"negativeInteger", "negativeInteger", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  642. {"nonNegativeInteger", "nonNegativeInteger", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  643. {"unsignedLong", "unsignedLong", "unsigned long", "???", "unsigned long", TK_UNSIGNEDLONG, 0, EAM_basic},
  644. {"unsignedInt", "unsignedInt", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  645. {"unsigned", "unsignedInt", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  646. {"unsignedShort", "unsignedShort", "unsigned short", "???", "unsigned short", TK_UNSIGNEDSHORT, 0, EAM_basic},
  647. {"unsignedByte", "unsignedByte", "unsigned char", "???", "unsigned char", TK_UNSIGNEDCHAR, 0, EAM_basic},
  648. {"positiveInteger", "positiveInteger", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  649. {"base64Binary", "base64Binary", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  650. {"normalizedString", "normalizedString", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  651. {"xsdString", "string", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  652. {"xsdBinary", "binary", "MemoryBuffer", "???", "const MemoryBuffer &", TK_STRUCT, (PF_REF), EAM_jmbin},
  653. {"xsdBoolean", "boolean", "bool", "???", "bool", TK_BOOL, 0, EAM_basic},
  654. {"xsdDecimal", "decimal", "float", "???", "float", TK_FLOAT, 0, EAM_basic},
  655. {"xsdInteger", "integer", "int", "???", "int", TK_INT, 0, EAM_basic},
  656. {"xsdByte", "byte", "unsigned char", "???", "unsigned char", TK_UNSIGNEDCHAR, 0, EAM_basic},
  657. {"xsdDuration", "duration", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  658. {"xsdDateTime", "dateTime", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  659. {"xsdTime", "time", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  660. {"xsdDate", "date", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  661. {"xsdYearMonth", "gYearMonth", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  662. {"xsdYear", "gYear", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  663. {"xsdMonthDay", "gMonthDay", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  664. {"xsdDay", "gDay", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  665. {"xsdMonth", "gMonth", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  666. {"xsdAnyURI", "anyURI", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  667. {"xsdQName", "QName", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  668. {"xsdNOTATION", "NOTATION", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  669. {"xsdToken", "token", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  670. {"xsdLanguage", "language", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  671. {"xsdNMTOKEN", "NMTOKEN", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  672. {"xsdNMTOKENS", "NMTOKENS", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  673. {"xsdName", "Name", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  674. {"xsdNCName", "NCName", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  675. {"xsdID", "ID", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  676. {"xsdIDREF", "IDREF", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  677. {"xsdIDREFS", "IDREFS", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  678. {"xsdENTITY", "ENTITY", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  679. {"xsdENTITIES", "ENTITIES", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  680. {"xsdNonPositiveInteger", "nonPositiveInteger", "int", "???", "int", TK_INT, 0, EAM_basic},
  681. {"xsdNegativeInteger", "negativeInteger", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  682. {"xsdNonNegativeInteger", "nonNegativeInteger", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  683. {"xsdUnsignedLong", "unsignedLong", "unsigned long", "???", "unsigned long", TK_UNSIGNEDLONG, 0, EAM_basic},
  684. {"xsdUnsignedInt", "unsignedInt", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  685. {"xsdUnsignedShort", "unsignedShort", "unsigned short", "???", "unsigned short", TK_UNSIGNEDSHORT, 0, EAM_basic},
  686. {"xsdUnsignedByte", "unsignedByte", "unsigned char", "???", "unsigned char", TK_UNSIGNEDCHAR, 0, EAM_basic},
  687. {"xsdPositiveInteger", "positiveInteger", "unsigned int", "???", "unsigned int", TK_UNSIGNED, 0, EAM_basic},
  688. {"xsdBase64Binary", "base64Binary", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  689. {"xsdNormalizedString", "normalizedString", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  690. {"EspTextFile", "string", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  691. {"EspResultSet", "string", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  692. {"AdoDataSet", "tns:AdoDataSet", "StringBuffer", "StringArray", "const char *", TK_CHAR, (PF_PTR|PF_CONST), EAM_jsbuf},
  693. {NULL, NULL, NULL, NULL, NULL, TK_null, 0, EAM_basic}
  694. };
  695. esp_xlate_info *esp_xlat(const char *from, bool defaultToString)
  696. {
  697. if (from)
  698. {
  699. for (unsigned i=0; esp_xlate_table[i].meta_type!=NULL; i++)
  700. {
  701. if (stricmp(from,esp_xlate_table[i].meta_type)==0)
  702. return &esp_xlate_table[i];
  703. }
  704. }
  705. return (defaultToString) ? &esp_xlate_table[0] : NULL;
  706. }
  707. //TODO: this is not bullet proof. better idea??
  708. // Return: NULL if no need to be defined, otherwise the type to be defined
  709. // Note: the caller needs to free memory
  710. static char* getToBeDefinedType(const char* type)
  711. {
  712. const char* colon = strchr(type, ':');
  713. const char* bareType = colon ? colon+1 : type;
  714. if (strnicmp(type, "xsd",colon-type)==0)
  715. return NULL;
  716. /*
  717. for (unsigned i=0; esp_xlate_table[i].meta_type!=NULL; i++)
  718. {
  719. if (stricmp(bareType,esp_xlate_table[i].xsd_type)==0)
  720. return NULL;
  721. }
  722. */
  723. if (strnicmp(type, "tns", colon-type)!=0)
  724. {
  725. char msg[128];
  726. sprintf(msg, "*** unhandled type: %s", type);
  727. outs(msg);
  728. yyerror(msg);
  729. return NULL;
  730. }
  731. if (strncmp(bareType, "ArrayOf", sizeof("ArrayOf")-1)==0)
  732. return strdup(bareType+sizeof("ArrayOf")-1);
  733. else
  734. return strdup(bareType);
  735. }
  736. static const char *MetaTypeToXsdType(const char *val)
  737. {
  738. esp_xlate_info *xlation=esp_xlat(val);
  739. return (xlation) ? xlation->xsd_type : (const char *)"string";
  740. }
  741. // return: true if the ver tag is defined
  742. bool hasMetaVerInfo(MetaTagInfo *list, const char* tag)
  743. {
  744. double ver = getMetaDouble(list,tag,-1);
  745. if (ver>0)
  746. return true;
  747. const char* vs = getMetaString(list,tag, NULL);
  748. if (vs!=NULL)
  749. return true;
  750. const char* id = getMetaConstId(list,tag,NULL);
  751. if (id)
  752. return true;
  753. return false;
  754. }
  755. bool getMetaVerInfo(MetaTagInfo *list, const char* tag, StrBuffer& s)
  756. {
  757. double ver = getMetaDouble(list,tag,-1);
  758. if (ver>0) {
  759. s.append(ver);
  760. return true;
  761. }
  762. const char* vs = getMetaString(list,tag, NULL);
  763. if (vs!=NULL) {
  764. if (*vs=='"' || *vs=='\'')
  765. vs++;
  766. double v = atof(vs);
  767. s.append(v);
  768. return true;
  769. }
  770. const char* id = getMetaConstId(list,tag,NULL);
  771. if (id) {
  772. s.append(id);
  773. return true;
  774. }
  775. return false;
  776. }
  777. static esp_xlate_info *esp_xlat(ParamInfo *pi)
  778. {
  779. char metatype[256];
  780. *metatype=0;
  781. pi->cat_type(metatype);
  782. return esp_xlat(metatype);
  783. }
  784. void ParamInfo::setXsdType(const char *value)
  785. {
  786. if (xsdtype)
  787. free(xsdtype);
  788. const char *newValue=value;
  789. if (strncmp(value, "xsd", 3)==0)
  790. newValue=MetaTypeToXsdType(value);
  791. xsdtype = (newValue!=NULL) ? strdup(newValue) : NULL;
  792. }
  793. const char *ParamInfo::getXsdType()
  794. {
  795. if (xsdtype==NULL)
  796. {
  797. char metatype[256];
  798. *metatype=0;
  799. cat_type(metatype);
  800. setXsdType(MetaTypeToXsdType(metatype));
  801. }
  802. return xsdtype;
  803. }
  804. const char* ParamInfo::getArrayImplType()
  805. {
  806. if (m_arrayImplType)
  807. return m_arrayImplType->str();
  808. if (isPrimitiveArray())
  809. {
  810. char metatype[256];
  811. metatype[0] = 0;
  812. cat_type(metatype);
  813. esp_xlate_info *xlation=esp_xlat(metatype, false);
  814. m_arrayImplType = new StrBuffer(xlation->array_type);
  815. }
  816. else
  817. {
  818. if (kind == TK_ESPENUM)
  819. m_arrayImplType = new VStrBuffer("%sArray", typname);
  820. else
  821. m_arrayImplType = new VStrBuffer("IArrayOf<IConst%s>", typname);
  822. }
  823. return m_arrayImplType->str();
  824. }
  825. const char* ParamInfo::getArrayItemXsdType()
  826. {
  827. switch (kind)
  828. {
  829. case TK_CHAR: return "string";
  830. case TK_UNSIGNEDCHAR: return "string"; //?
  831. case TK_BYTE: return "byte";
  832. case TK_BOOL: return "boolean";
  833. case TK_SHORT: return "short";
  834. case TK_UNSIGNEDSHORT: return "unsignedShort";
  835. case TK_INT: return "int";
  836. case TK_UNSIGNED: return "unsignedInt";
  837. case TK_LONG: return "long";
  838. case TK_UNSIGNEDLONG: return "unsignedLong";
  839. case TK_LONGLONG: return "long";
  840. case TK_UNSIGNEDLONGLONG: return "unsignedLong";
  841. case TK_DOUBLE: return "double";
  842. case TK_FLOAT: return "float";
  843. case TK_null: return "string";
  844. case TK_STRUCT:
  845. case TK_VOID:
  846. case TK_ESPSTRUCT:
  847. case TK_ESPENUM:
  848. default: throw "Unimplemented";
  849. }
  850. }
  851. const char* ParamInfo::getArrayItemTag()
  852. {
  853. const char *item_tag = getMetaString("item_tag", NULL);
  854. if (item_tag)
  855. return item_tag;
  856. if (!(flags & PF_TEMPLATE) || !streq(templ, "ESParray"))
  857. return NULL;
  858. if (isEspStringArray())
  859. return "Item";
  860. return typname;
  861. }
  862. void ParamInfo::write_esp_declaration()
  863. {
  864. char metatype[256];
  865. *metatype=0;
  866. cat_type(metatype);
  867. esp_xlate_info *xlation=esp_xlat(metatype, false);
  868. if (hasNameTag())
  869. outf("\tSoapStringParam m_%s_name;\n", name);
  870. if (xlation)
  871. {
  872. if (xlation->eam_type==EAM_jmbin)
  873. {
  874. if (getMetaInt("attach", 0))
  875. outf("\tSoapAttachBinary m_%s;\n", name);
  876. else
  877. outf("\tSoapParamBinary m_%s;\n", name);
  878. }
  879. else
  880. {
  881. if (getMetaInt("attach", 0))
  882. {
  883. if (!stricmp(xlation->store_type, "StringBuffer"))
  884. outf("\tSoapAttachString m_%s;\n", name);
  885. else
  886. outf("\tSoapAttachParam<%s> m_%s;\n", xlation->store_type, name);
  887. }
  888. else if (flags & PF_TEMPLATE)
  889. // outf("\tSoapArrayParam<%s> m_%s;\n", xlation->array_type, name);
  890. outf("\tSoap%s m_%s;\n", xlation->array_type, name);
  891. else if (!stricmp(xlation->store_type, "StringBuffer"))
  892. outf("\tSoapStringParam m_%s;\n", name);
  893. else
  894. outf("\tSoapParam<%s> m_%s;\n", xlation->store_type, name);
  895. }
  896. }
  897. else
  898. {
  899. if (getMetaInt("attach", 0))
  900. outf("\tSoapAttachString m_%s;\n", name);
  901. else if (flags & PF_TEMPLATE && templ && !strcmp(templ, "ESParray"))
  902. {
  903. if (isEspStringArray())
  904. //outf("\tSoapArrayParam<StringArray> m_%s;\n", name);
  905. outf("\tSoapStringArray m_%s;\n", name);
  906. else if (kind==TK_ESPENUM)
  907. outf("\tSoapEnumArrayParam<C%s, CX%s, %sArray> m_%s;\n", typname, typname, typname, name);
  908. else
  909. outf("\tSoapStructArrayParam<IConst%s, C%s> m_%s;\n", typname, typname, name);
  910. }
  911. else if (kind==TK_ESPSTRUCT)
  912. outf("\tSoapStruct<C%s, IConst%s> m_%s;\n", typname, typname, name);
  913. else if (kind==TK_ESPENUM)
  914. outf("\tCX%s m_%s;\n", typname, name);
  915. else
  916. outf("\tSoapStringParam m_%s;\n", name);
  917. }
  918. }
  919. void ParamInfo::write_esp_init(bool &isFirst, bool msgRemoveNil)
  920. {
  921. outs(isFirst ? "\n\t: " : ",");
  922. MetaTagInfo* deftag = findMetaTag(tags, "default");
  923. bool removeNil = (msgRemoveNil || findMetaTag(tags, "nil_remove")!=NULL);
  924. const char *nilStr = (removeNil) ? "nilRemove" : "nilIgnore";
  925. if (kind==TK_ESPSTRUCT)
  926. {
  927. outf("m_%s(serviceName, %s)", name, nilStr);
  928. }
  929. else if (kind==TK_ESPENUM)
  930. {
  931. if (deftag)
  932. {
  933. outf("m_%s(", name);
  934. switch(deftag->mttype_)
  935. {
  936. case MetaTagInfo::mt_string: outf("%s",deftag->getString()); break;
  937. case MetaTagInfo::mt_int: outf("\"%d\"", deftag->getInt()); break;
  938. case MetaTagInfo::mt_double: outf("\"%g\"", deftag->getDouble()); break;
  939. case MetaTagInfo::mt_const_id: outf("\"%s\"", deftag->getName()); break;
  940. case MetaTagInfo::mt_none: assert(false); break;
  941. }
  942. outf(")");
  943. }
  944. else
  945. outf("m_%s(%s)", name, nilStr);
  946. }
  947. else if ((flags & PF_TEMPLATE) || kind==TK_STRUCT || getMetaInt("attach", 0))
  948. {
  949. outf("m_%s(%s)", name, nilStr);
  950. }
  951. else if (deftag)
  952. {
  953. if (deftag->mttype_==MetaTagInfo::mt_string)
  954. outf("m_%s(%s, %s)", name, deftag->getString(), nilStr);
  955. else if (deftag->mttype_==MetaTagInfo::mt_int)
  956. outf("m_%s(%d, %s,false)", name, deftag->getInt(), nilStr);
  957. else if (deftag->mttype_==MetaTagInfo::mt_double)
  958. outf("m_%s(%g, %s,false)", name, deftag->getDouble(), nilStr);
  959. }
  960. else
  961. {
  962. if (getMetaInt("http_nillable", 1)!=0)
  963. outf("m_%s(%s)", name, nilStr);
  964. else
  965. outf("m_%s(%s, false)", name, nilStr);
  966. }
  967. isFirst=false;
  968. }
  969. void ParamInfo::write_esp_attr_method(const char *msgname, bool isSet, bool parNilRemove, bool isDecl, bool isPure, bool parTrim, const char* xsdType)
  970. {
  971. char metatype[256];
  972. *metatype=0;
  973. cat_type(metatype);
  974. esp_xlate_info *xlation=esp_xlat(metatype);
  975. char *methName=strdup(name);
  976. *methName=upperchar(*methName);
  977. const char *httpcont = getMetaString("http_content", NULL);
  978. bool hasNilRemove = (parNilRemove || getMetaInt("nil_remove"));
  979. bool hasTrim = (parTrim || getMetaInt("trim"));
  980. if (hasNameTag())
  981. {
  982. if (isSet)
  983. {
  984. if (isDecl)
  985. outs("\t");
  986. if (isDecl && isPure)
  987. outs("virtual ");
  988. outs("void ");
  989. if (!isDecl && msgname)
  990. outf("C%s::", msgname);
  991. outf("set%s_name", methName);
  992. outs("(const char * val)");
  993. if (isDecl)
  994. outs((isPure) ? "=0;\n" : ";\n");
  995. else
  996. outf("{ m_%s_name.set(val); }\n", name);
  997. }
  998. else
  999. {
  1000. if (isDecl)
  1001. outs("\t");
  1002. if (isDecl && isPure)
  1003. outs("virtual ");
  1004. outs("const char *");
  1005. if (!isDecl && msgname)
  1006. outf("C%s::", msgname);
  1007. outf("get%s_name()", methName);
  1008. if (isDecl)
  1009. outs((isPure) ? "=0;\n" : ";\n");
  1010. else
  1011. outf("{ return m_%s_name.query(); }\n", name);
  1012. if (isDecl)
  1013. outs("\t");
  1014. if (isDecl && isPure)
  1015. outs("virtual ");
  1016. outs("const StringBuffer& ");
  1017. if (!isDecl && msgname)
  1018. outf("C%s::", msgname);
  1019. outf("get%s_value()", methName);
  1020. if (isDecl)
  1021. outs((isPure) ? "=0;\n" : ";\n");
  1022. else
  1023. outf("{ return m_%s.getValue(); }\n", name);
  1024. }
  1025. }
  1026. if (httpcont!=NULL)
  1027. {
  1028. if (isSet)
  1029. {
  1030. if (isDecl)
  1031. outs("\t");
  1032. if (isDecl && isPure)
  1033. outs("virtual ");
  1034. outs("void ");
  1035. if (!isDecl && msgname)
  1036. outf("C%s::", msgname);
  1037. outf("set%s_mimetype", methName);
  1038. outs("(const char * val)");
  1039. if (isDecl)
  1040. outs((isPure) ? "=0;\n" : ";\n");
  1041. else
  1042. outf("{ m_%s_mimetype.set(val); }\n", name);
  1043. }
  1044. else
  1045. {
  1046. if (isDecl)
  1047. outs("\t");
  1048. if (isDecl && isPure)
  1049. outs("virtual ");
  1050. outs("const char *");
  1051. if (!isDecl && msgname)
  1052. outf("C%s::", msgname);
  1053. outf("get%s_mimetype()", methName);
  1054. if (isDecl)
  1055. outs((isPure) ? "=0;\n" : ";\n");
  1056. else
  1057. outf("{ return m_%s_mimetype.str(); }\n", name);
  1058. }
  1059. }
  1060. if (isSet)
  1061. {
  1062. if (hasNilRemove && xlation->eam_type == EAM_basic && (flags & PF_TEMPLATE)==0 )
  1063. {
  1064. if (isDecl)
  1065. outs("\t");
  1066. if (isDecl && isPure)
  1067. outs("virtual ");
  1068. outs("void ");
  1069. if (!isDecl && msgname)
  1070. outf("C%s::", msgname);
  1071. outf("set%s_null()", methName);
  1072. if (isDecl)
  1073. outs((isPure) ? "=0;\n" : ";\n");
  1074. else
  1075. outf("{ m_%s.Nil(); }", name);
  1076. }
  1077. if (isDecl)
  1078. outs("\t");
  1079. if (isDecl && isPure)
  1080. outs("virtual ");
  1081. if (flags & PF_TEMPLATE)
  1082. {
  1083. // setXXX(IArrayOf<IEspXXX>);
  1084. if (templ && !strcmp(templ, "ESParray") && typname && !isEspStringArray() && kind!=TK_ESPENUM)
  1085. {
  1086. outs("void ");
  1087. if (!isDecl && msgname)
  1088. outf("C%s::", msgname);
  1089. outf("set%s", methName);
  1090. if (kind == TK_ESPENUM)
  1091. ;// outf("(%sArray &val)", typname);
  1092. else
  1093. outf("(IArrayOf<IEsp%s> &val)", typname);
  1094. if (isDecl)
  1095. {
  1096. if (isPure)
  1097. outs("=0;\n\tvirtual ");
  1098. else
  1099. outs(";\n ");
  1100. }
  1101. else
  1102. {
  1103. outs("\n{\n");
  1104. if (kind == TK_ESPENUM)
  1105. {
  1106. /*
  1107. outf("\tm_%s->kill();\n", name);
  1108. outf("\t%sArray &target = m_%s.getValue();\n", typname, name);
  1109. outs("\tForEachItemIn(idx, val)\n");
  1110. outs("\t{\n");
  1111. outf("\t\tC%s &item = (val).item(idx);\n", typname);
  1112. outs("\t\ttarget.append(item);\n");
  1113. outs("\t}\n");
  1114. */
  1115. }
  1116. else
  1117. {
  1118. outf("\tm_%s->kill();\n", name);
  1119. outf("\tIArrayOf<IConst%s> &target = m_%s.getValue();\n", typname, name);
  1120. outs("\tForEachItemIn(idx, val)\n");
  1121. outs("\t{\n");
  1122. outf("\t\tIEsp%s &item = (val).item(idx);\n", typname);
  1123. outs("\t\titem.Link();\n");
  1124. outs("\t\ttarget.append(item);\n");
  1125. outs("\t}\n");
  1126. }
  1127. outs("}\n");
  1128. }
  1129. }
  1130. outs("void ");
  1131. if (!isDecl && msgname)
  1132. outf("C%s::", msgname);
  1133. outf("set%s", methName);
  1134. if (templ && !strcmp(templ, "ESParray"))
  1135. {
  1136. //if (isEspStringArray())
  1137. // outf("(%s &val)", "StringArray");
  1138. //else
  1139. // outf("(IArrayOf<IConst%s> &val)", typname);
  1140. outf("(%s &val)", getArrayImplType());
  1141. }
  1142. else
  1143. {
  1144. switch (xlation->eam_type)
  1145. {
  1146. case EAM_jmbuf:
  1147. outf("(%s val, unsigned int len)", xlation->access_type);
  1148. break;
  1149. case EAM_jmbin:
  1150. case EAM_basic:
  1151. case EAM_jsbuf:
  1152. default:
  1153. outf("(%s val)", xlation->access_type);
  1154. break;
  1155. }
  1156. }
  1157. if (isDecl)
  1158. {
  1159. if (isPure)
  1160. outs("=0");
  1161. outs(";\n");
  1162. }
  1163. else
  1164. {
  1165. if (isPrimitiveArray())
  1166. {
  1167. outf("{ ");
  1168. if (isEspStringArray())
  1169. outf("m_%s->kill(); ",name);
  1170. outf(" CloneArray(m_%s.getValue(), val); }\n", name);
  1171. }
  1172. else if (kind == TK_ESPENUM)
  1173. {
  1174. outs("\n{\n");
  1175. outf("\tm_%s->kill();\n", name);
  1176. outf("\t%sArray &target = m_%s.getValue();\n", typname, name);
  1177. outs("\tForEachItemIn(idx, val)\n");
  1178. outs("\t{\n");
  1179. outf("\t\tC%s item = val.item(idx);\n", typname);
  1180. outs("\t\ttarget.append(item);\n");
  1181. outs("\t}\n");
  1182. outs("}\n");
  1183. }
  1184. else
  1185. {
  1186. outs("\n{\n");
  1187. outf("\tm_%s->kill();\n", name);
  1188. outf("\tIArrayOf<IConst%s> &target = m_%s.getValue();\n", typname, name);
  1189. outs("\tForEachItemIn(idx, val)\n");
  1190. outs("\t{\n");
  1191. outf("\t\tIConst%s &item = val.item(idx);\n", typname);
  1192. outs("\t\titem.Link();\n");
  1193. outs("\t\ttarget.append(item);\n");
  1194. outs("\t}\n");
  1195. outs("}\n");
  1196. }
  1197. }
  1198. } // flags & PF_TEMPLATE
  1199. else if (kind==TK_ESPSTRUCT)
  1200. {
  1201. outf("IEsp%s & ", typname);
  1202. if (!isDecl && msgname)
  1203. outf("C%s::", msgname);
  1204. outf("update%s()", methName);
  1205. if (isDecl)
  1206. {
  1207. if (isPure)
  1208. outs("=0;\n");
  1209. else
  1210. outs(";\n");
  1211. }
  1212. else
  1213. {
  1214. outf("{ return (IEsp%s &) m_%s.getValue(); }\n", typname, name);
  1215. }
  1216. if (isDecl)
  1217. outs("\t");
  1218. if (isDecl && isPure)
  1219. outs("virtual ");
  1220. outs("void ");
  1221. if (!isDecl && msgname)
  1222. outf("C%s::", msgname);
  1223. outf("set%s(IConst%s &ifrom)", methName, typname);
  1224. if (isDecl)
  1225. {
  1226. if (isPure)
  1227. outs("=0");
  1228. outs(";\n");
  1229. }
  1230. else
  1231. {
  1232. outf("{ m_%s.copy(ifrom); }\n", name);
  1233. }
  1234. }
  1235. else if (kind==TK_ESPENUM)
  1236. {
  1237. outs("void ");
  1238. if (!isDecl && msgname)
  1239. outf("C%s::", msgname);
  1240. outf("set%s(C%s val)",methName, typname);
  1241. if (isDecl)
  1242. {
  1243. if (isPure)
  1244. outs("=0");
  1245. outs(";\n");
  1246. }
  1247. else
  1248. outf(" { m_%s.setValue(val); }\n", name);
  1249. // as string
  1250. if (isDecl && isPure)
  1251. outs("\tvirtual void ");
  1252. else
  1253. outs("void ");
  1254. if (!isDecl && msgname)
  1255. outf("C%s::",msgname);
  1256. outf("set%s(const char* val)", methName);
  1257. if (isDecl)
  1258. {
  1259. if (isPure)
  1260. outs("=0");
  1261. outs(";\n");
  1262. }
  1263. else
  1264. outf(" { m_%s.setValue(val); }\n", name);
  1265. }
  1266. else
  1267. {
  1268. //else
  1269. {
  1270. outs("void ");
  1271. if (!isDecl && msgname)
  1272. outf("C%s::", msgname);
  1273. outf("set%s", methName);
  1274. switch (xlation->eam_type)
  1275. {
  1276. case EAM_jmbuf:
  1277. outf("(%s val, unsigned int len)", xlation->access_type);
  1278. break;
  1279. case EAM_jsbuf:
  1280. //if (xsdType)
  1281. // outf("(%s val, IEspContext& ctx)", xlation->access_type);
  1282. //else
  1283. outf("(%s val)", xlation->access_type);
  1284. break;
  1285. case EAM_jmbin:
  1286. case EAM_basic:
  1287. default:
  1288. outf("(%s val)", xlation->access_type);
  1289. break;
  1290. }
  1291. if (isDecl)
  1292. {
  1293. if (isPure)
  1294. outs("=0");
  1295. outs(";\n");
  1296. }
  1297. else
  1298. {
  1299. //outf("{ m_%s", name);
  1300. switch (xlation->eam_type)
  1301. {
  1302. case EAM_jsbuf:
  1303. // TODO: can not handle ArrayOfXXX yet
  1304. /**
  1305. if (xsdType && strncmp(xsdType,"ArrayOf",7)!=0)
  1306. {
  1307. //do a deserialization to enforce the versioning
  1308. outf("\n{\n");
  1309. outf("\tif (ctx)\n");
  1310. outf("\t{\n");
  1311. outf("\t\tXmlPullParser xpp(val,strlen(val));\n");
  1312. outf("\t\tCRpcMessage msg;\n");
  1313. outf("\t\tmsg.unmarshall(&xpp);\n");
  1314. outf("\t\tStringBuffer s;\n");
  1315. outf("\t\tC%s tmp(\"%s\");\n", xsdType, "XX"); // msgname?: not right
  1316. outf("\t\ttmp.unserialize(msg,NULL,\"%s\");\n", name);
  1317. outf("\t\tC%s::serializer(ctx,tmp,s,false);\n",xsdType);
  1318. outf("\t\tm_%s.set(s.str()%s); \n", name, hasTrim?",true":"");
  1319. outf("\t}\n");
  1320. outf("\telse\n");
  1321. outf("\t\tm_%s.set(val%s);\n",name,hasTrim?",true":"");
  1322. outf("}\n");
  1323. }
  1324. else
  1325. */
  1326. outf("{ m_%s.set(val%s); }\n", name, hasTrim?",true":"");
  1327. break;
  1328. case EAM_jmbin:
  1329. outf("{ m_%s->clear().append(val); }\n", name);
  1330. break;
  1331. case EAM_jmbuf:
  1332. outf("{ m_%s->set(len, val); }\n", name);
  1333. break;
  1334. case EAM_basic:
  1335. default:
  1336. outf("{ m_%s=val; }\n", name);
  1337. break;
  1338. }
  1339. }
  1340. }
  1341. }
  1342. }
  1343. else // get function
  1344. {
  1345. if (hasNilRemove && xlation->eam_type == EAM_basic && (flags & PF_TEMPLATE)==0 )
  1346. {
  1347. if (isDecl && isPure)
  1348. outs("\tvirtual ");
  1349. outf("bool ");
  1350. if (!isDecl && msgname)
  1351. outf("C%s::", msgname);
  1352. outf("get%s_isNull()", methName);
  1353. if (isDecl)
  1354. outs((isPure) ? "=0;\n" : ";\n");
  1355. else
  1356. outf("{return m_%s.is_nil();}\n", name);
  1357. }
  1358. if (isDecl)
  1359. outs("\t");
  1360. if (isDecl && isPure)
  1361. outs("virtual ");
  1362. if (flags & PF_TEMPLATE)
  1363. {
  1364. outf("%s & ",getArrayImplType());
  1365. if (!isDecl && msgname)
  1366. outf("C%s::",msgname);
  1367. outf("get%s()", methName);
  1368. }
  1369. else if (kind==TK_ESPSTRUCT)
  1370. {
  1371. outf("IConst%s & ", typname);
  1372. if (!isDecl && msgname)
  1373. outf("C%s::", msgname);
  1374. outf("get%s()", methName);
  1375. }
  1376. else if (kind==TK_ESPENUM)
  1377. {
  1378. outf("C%s ", typname);
  1379. if (!isDecl && msgname)
  1380. outf("C%s::", msgname);
  1381. outf("get%s()", methName);
  1382. }
  1383. else
  1384. {
  1385. switch (xlation->eam_type)
  1386. {
  1387. case EAM_jmbuf:
  1388. outs("void ");
  1389. if (!isDecl && msgname)
  1390. outf("C%s::", msgname);
  1391. outf("get%s(%s val, unsigned int len)", methName, xlation->access_type);
  1392. break;
  1393. case EAM_jmbin:
  1394. case EAM_basic:
  1395. case EAM_jsbuf:
  1396. default:
  1397. outf("%s ", xlation->access_type);
  1398. if (!isDecl && msgname)
  1399. outf("C%s::", msgname);
  1400. outf("get%s()", methName);
  1401. break;
  1402. }
  1403. }
  1404. if (isDecl)
  1405. {
  1406. if (isPure)
  1407. outs("=0");
  1408. outs(";\n");
  1409. }
  1410. else
  1411. {
  1412. if (kind==TK_ESPSTRUCT)
  1413. {
  1414. outf(" { return (IConst%s &) m_%s.getValue();}\n", typname, name);
  1415. }
  1416. else if (kind==TK_ESPENUM)
  1417. {
  1418. outf(" { return m_%s.getValue(); }\n", name);
  1419. }
  1420. else if (flags & PF_TEMPLATE)
  1421. {
  1422. outf(" { return (%s &) m_%s; }\n", getArrayImplType(), name);
  1423. }
  1424. else
  1425. {
  1426. switch (xlation->eam_type)
  1427. {
  1428. case EAM_jsbuf:
  1429. outf(" { return m_%s.query();}\n", name);
  1430. break;
  1431. case EAM_jmbuf:
  1432. outf(" { m_%s->read(len, val);}\n", name);
  1433. break;
  1434. case EAM_jmbin:
  1435. outf(" { return m_%s.getValue();}\n", name);
  1436. break;
  1437. case EAM_basic:
  1438. default:
  1439. outf(" { return m_%s;}\n", name);
  1440. break;
  1441. }
  1442. }
  1443. }
  1444. // additonal method
  1445. switch(kind)
  1446. {
  1447. case TK_ESPENUM:
  1448. // getXXAsString
  1449. if (!(flags & PF_TEMPLATE))
  1450. {
  1451. if (isDecl)
  1452. outs("\t");
  1453. if (isDecl && isPure)
  1454. outs("virtual ");
  1455. outs("const char* ");
  1456. if (!isDecl && msgname)
  1457. outf("C%s::", msgname);
  1458. outf("get%sAsString()", methName);
  1459. if (isDecl)
  1460. {
  1461. if (isPure)
  1462. outs("=0");
  1463. outs(";\n");
  1464. }
  1465. else
  1466. outf(" { return (const char*)m_%s; }\n", name);
  1467. }
  1468. break;
  1469. default:
  1470. // nothing to do
  1471. break;
  1472. }
  1473. }
  1474. free(methName);
  1475. }
  1476. void ParamInfo::write_esp_client_impl()
  1477. {
  1478. char *methName=strdup(name);
  1479. *methName=upperchar(*methName);
  1480. outf("\treq->set%s(%s_);\n", methName, name);
  1481. free(methName);
  1482. }
  1483. void ParamInfo::write_esp_param()
  1484. {
  1485. char metatype[256];
  1486. *metatype=0;
  1487. cat_type(metatype);
  1488. esp_xlate_info *xlation=esp_xlat(metatype);
  1489. if (kind==TK_ESPSTRUCT)
  1490. {
  1491. outf("IConst%s &%s_", typname, name);
  1492. }
  1493. else if (kind==TK_ESPENUM)
  1494. {
  1495. outf("C%s %s_", typname, name);
  1496. }
  1497. else
  1498. {
  1499. if (flags & PF_TEMPLATE)
  1500. {
  1501. if (templ && !strcmp(templ, "ESParray"))
  1502. {
  1503. /*if (isEspStringArray())
  1504. outf("StringArray &%s_", name);
  1505. else
  1506. outf("IArrayOf<IConst%s> &%s_", typname, name);
  1507. */
  1508. outf("%s &%s_", getArrayImplType(), name);
  1509. }
  1510. else
  1511. {
  1512. switch (xlation->eam_type)
  1513. {
  1514. case EAM_jmbuf:
  1515. outf("%s %s_, unsigned int %s_len)", xlation->access_type, name, name);
  1516. break;
  1517. case EAM_jmbin:
  1518. case EAM_basic:
  1519. case EAM_jsbuf:
  1520. default:
  1521. outf("%s %s_", xlation->access_type, name);
  1522. break;
  1523. }
  1524. }
  1525. }
  1526. else
  1527. {
  1528. switch (xlation->eam_type)
  1529. {
  1530. case EAM_jmbuf:
  1531. outf("%s %s_, unsigned int %s_len", xlation->access_type, name, name);
  1532. break;
  1533. case EAM_jmbin:
  1534. case EAM_basic:
  1535. case EAM_jsbuf:
  1536. default:
  1537. outf("%s %s_", xlation->access_type, name);
  1538. break;
  1539. }
  1540. }
  1541. }
  1542. }
  1543. void ParamInfo::write_clarion_attr_method(bool isSet)
  1544. {
  1545. ParamInfo *savenext = next;
  1546. char metatype[256]={0};
  1547. esp_xlate_info *xlation = NULL;
  1548. if (isESP && kind==TK_null)
  1549. {
  1550. xlation=esp_xlat(xsdtype);
  1551. if (xlation)
  1552. {
  1553. kind = xlation->access_kind;
  1554. flags |= xlation->access_flags;
  1555. cat_type(metatype);
  1556. }
  1557. }
  1558. else
  1559. {
  1560. cat_type(metatype);
  1561. xlation=esp_xlat(metatype);
  1562. }
  1563. char methName[256]={0};
  1564. const char *httpcont = getMetaString("http_content", NULL);
  1565. if (httpcont!=NULL)
  1566. {
  1567. ParamInfo strparm;
  1568. strparm.name = strdup("mimetype");
  1569. strparm.typname = strdup("const char *");
  1570. if (isSet)
  1571. {
  1572. ProcInfo setProc;
  1573. sprintf(methName, "set%s_mimetype", name);
  1574. methName[3]=upperchar(methName[3]);
  1575. setProc.name = strdup(methName);
  1576. setProc.params = &strparm;
  1577. setProc.out_clarion_method();
  1578. setProc.params = 0;
  1579. }
  1580. else
  1581. {
  1582. ProcInfo setProc;
  1583. sprintf(methName, "get%s_mimetype", name);
  1584. methName[3]=upperchar(methName[3]);
  1585. setProc.name = strdup(methName);
  1586. setProc.rettype = &strparm;
  1587. setProc.out_clarion_method();
  1588. setProc.rettype = 0;
  1589. }
  1590. }
  1591. ParamInfo lenparm;
  1592. lenparm.typname = strdup("unsigned int");
  1593. lenparm.name = strdup("len");
  1594. if (isSet)
  1595. {
  1596. ProcInfo setProc;
  1597. sprintf(methName, "set%s", name);
  1598. methName[3]=upperchar(methName[3]);
  1599. setProc.name = strdup(methName);
  1600. next = 0;
  1601. setProc.params = this;
  1602. switch (xlation->eam_type)
  1603. {
  1604. case EAM_jmbuf:
  1605. {
  1606. next = &lenparm;
  1607. setProc.out_clarion_method();
  1608. next=0;
  1609. break;
  1610. }
  1611. case EAM_jmbin:
  1612. case EAM_basic:
  1613. case EAM_jsbuf:
  1614. default:
  1615. setProc.out_clarion_method();
  1616. break;
  1617. }
  1618. setProc.params = 0;
  1619. }
  1620. else
  1621. {
  1622. ProcInfo getProc;
  1623. sprintf(methName, "get%s", name);
  1624. methName[3]=upperchar(methName[3]);
  1625. getProc.name = strdup(methName);
  1626. switch (xlation->eam_type)
  1627. {
  1628. case EAM_jmbuf:
  1629. {
  1630. next = 0;
  1631. getProc.params = this;
  1632. outf("void get%s(%s val, unsigned int len)", methName, xlation->access_type);
  1633. next = &lenparm;
  1634. getProc.out_clarion_method();
  1635. break;
  1636. }
  1637. case EAM_jmbin:
  1638. case EAM_basic:
  1639. case EAM_jsbuf:
  1640. default:
  1641. getProc.rettype = this;
  1642. getProc.out_clarion_method();
  1643. break;
  1644. }
  1645. getProc.params=0;
  1646. getProc.rettype=0;
  1647. }
  1648. next=savenext;
  1649. }
  1650. bool ParamInfo::write_mapinfo_check(int indents, const char* ctxvar)
  1651. {
  1652. StrBuffer minVer, maxVer, deprVer;
  1653. bool hasMin = getMetaVerInfo("min_ver", minVer);
  1654. bool hasMax = getMetaVerInfo("max_ver", maxVer);
  1655. bool hasDepr = getMetaVerInfo("depr_ver", deprVer);
  1656. bool hasOutput = false;
  1657. if (hasMin || hasDepr || hasMax)
  1658. {
  1659. hasOutput = true;
  1660. indent(indents);
  1661. outs("if ((clientVer==-1.0");
  1662. if (hasMin)
  1663. {
  1664. if (hasDepr)
  1665. outf(" || (clientVer>=%s && clientVer<%s))", minVer.str(), deprVer.str());
  1666. else if (hasMax)
  1667. outf(" || (clientVer>=%s && clientVer<=%s))", minVer.str(), maxVer.str());
  1668. else
  1669. outf(" || clientVer>=%s)", minVer.str());
  1670. }
  1671. else if (hasDepr)
  1672. outf(" || clientVer<%s)", deprVer.str());
  1673. else // maxVer>0
  1674. outf(" || clientVer<=%s)", maxVer.str());
  1675. }
  1676. if (ctxvar)
  1677. {
  1678. const char* optional = getMetaString("optional",NULL);
  1679. if (optional)
  1680. {
  1681. if (hasOutput)
  1682. outs(" && ");
  1683. else
  1684. {
  1685. indent(indents);
  1686. outs("if (");
  1687. hasOutput = true;
  1688. }
  1689. const char* quote = (*optional == '"') ? "":"\"";
  1690. outf("(!ctx || %s->checkOptional(%s%s%s))", ctxvar, quote,optional,quote);
  1691. }
  1692. }
  1693. if (hasOutput)
  1694. outs(")\n");
  1695. return hasOutput;
  1696. }
  1697. void ParamInfo::write_esp_marshall(bool isRpc, bool encodeXml, bool checkVer, int indents, bool encodeJson)
  1698. {
  1699. const char *soap_path=getMetaString("soap_path", NULL);
  1700. char *path = (soap_path!=NULL) ? strdup(soap_path) : NULL;
  1701. char *tagname = NULL;
  1702. if (path)
  1703. {
  1704. path[strlen(path)-1]=0;
  1705. path++;
  1706. tagname=strrchr(path, '/');
  1707. if (tagname)
  1708. {
  1709. *tagname=0;
  1710. tagname++;
  1711. }
  1712. else
  1713. {
  1714. tagname=path;
  1715. path= (char *) ""; // cast to kill a warning. Could recode to avoid more cleanly but this is obsolete code anyway
  1716. }
  1717. }
  1718. if (checkVer)
  1719. {
  1720. if (write_mapinfo_check(indents,"ctx"))
  1721. indents++;
  1722. }
  1723. if (!isEspArrayOf() && getMetaInt("encode_newlines", -1)!=-1)
  1724. {
  1725. indent(indents);
  1726. outf("m_%s.setEncodeNewlines(true);\n", name);
  1727. }
  1728. indent(indents);
  1729. if (isRpc)
  1730. outf("m_%s.marshall(rpc_resp, ", name);
  1731. else
  1732. outf("m_%s.toStr(ctx, buffer, ", name);
  1733. if (isEspArrayOf())
  1734. {
  1735. if (path)
  1736. outf("\"%s\", \"%s\", \"%s\");\n", tagname, getArrayItemTag(), path);
  1737. else
  1738. outf("\"%s\", \"%s\");\n", getXmlTag(), getArrayItemTag());
  1739. }
  1740. else
  1741. {
  1742. const char *prefix = getMetaString("ns_var", "\"\"");
  1743. const char *encode = encodeXml ? "true" : "false";
  1744. if (path)
  1745. {
  1746. outf("\"%s\", \"%s\"", tagname, path);
  1747. if (isRpc)
  1748. outf(", \"\", %s", prefix);
  1749. else if (kind!=TK_ESPSTRUCT)
  1750. outf(", %s", encode);
  1751. outs(");\n");
  1752. }
  1753. else if (!getMetaInt("attribute"))
  1754. {
  1755. outf("\"%s\", \"\", ", getXmlTag());
  1756. if (isRpc)
  1757. outf("\"\", %s);\n", prefix);
  1758. else if (kind==TK_ESPSTRUCT)
  1759. outf("false, \"\", %s);\n", prefix);
  1760. else
  1761. {
  1762. outf("%s, \"\", %s", encode, prefix);
  1763. if (getMetaInt("json_inline", !encodeJson))
  1764. outs(", false");
  1765. outs(");\n");
  1766. }
  1767. }
  1768. }
  1769. }
  1770. const char* ParamInfo::getOptionalParam()
  1771. {
  1772. static StrBuffer optGroup;
  1773. StrBuffer optional;
  1774. optGroup.clear();
  1775. if (getMetaStringValue(optional,"optional"))
  1776. optGroup.appendf(", \"%s\"", optional.str());
  1777. return optGroup.str();
  1778. }
  1779. void ParamInfo::write_esp_unmarshall(const char *rpcvar, bool useBasePath, int indents)
  1780. {
  1781. const char *soap_path=getMetaString("soap_path", NULL);
  1782. char *path = (soap_path!=NULL) ? strdup(soap_path) : NULL;
  1783. if (path && *path)
  1784. {
  1785. path[strlen(path)-1]=0;
  1786. path++;
  1787. char *tagname=strrchr((char *)path, '/');
  1788. indent(indents);
  1789. if (tagname)
  1790. {
  1791. *tagname=0;
  1792. tagname++;
  1793. outf("hasValue |= m_%s.unmarshall(%s, \"%s\", \"%s\"%s);\n", name, rpcvar, tagname, path, getOptionalParam());
  1794. }
  1795. else
  1796. {
  1797. outf("hasValue |= m_%s.unmarshall(%s, \"%s\"%s);\n", name, rpcvar, path, getOptionalParam());
  1798. }
  1799. }
  1800. else
  1801. {
  1802. bool isAttr = getMetaInt("attribute")!=0;
  1803. indent(indents);
  1804. outf("hasValue |= m_%s.unmarshall(%s, \"%s%s\"%s%s);\n", name, rpcvar, isAttr ? "@" : "",getXmlTag(), (useBasePath) ? ", basepath" : "", getOptionalParam());
  1805. }
  1806. free(path);
  1807. }
  1808. void ParamInfo::write_esp_unmarshall_properties(const char *propvar, const char *attachvar, int indents)
  1809. {
  1810. indent(indents);
  1811. const char* at = getMetaInt("attribute") ? "@" : "";
  1812. outf("hasValue |= m_%s.unmarshall(ctx, %s, %s, \"%s%s\", basepath%s);\n", name, propvar, attachvar, at, getXmlTag(), getOptionalParam());
  1813. }
  1814. void ParamInfo::write_esp_unmarshall_attachments(const char *propvar, const char *attachvar, int indents)
  1815. {
  1816. indent(indents);
  1817. const char* at = getMetaInt("attribute") ? "@" : "";
  1818. outf("hasValue |= m_%s.unmarshallAttach(ctx, %s, %s, \"%s%s\", basepath%s);\n", name, propvar, attachvar, at, getXmlTag(), getOptionalParam());
  1819. }
  1820. void ParamInfo::write_esp_unmarshall_soapval(const char *var, int indents)
  1821. {
  1822. indent(indents);
  1823. const char* at = getMetaInt("attribute") ? "@" : "";
  1824. outf("hasValue |= m_%s.unmarshall(ctx, %s, \"%s%s\"%s);\n", name, var, at, getXmlTag(), getOptionalParam());
  1825. }
  1826. //-------------------------------------------------------------------------------------------------------------
  1827. // class ProcInfo
  1828. ProcInfo::ProcInfo()
  1829. {
  1830. name = NULL;
  1831. rettype = NULL;
  1832. params = NULL;
  1833. next = NULL;
  1834. conntimeout = NULL;
  1835. calltimeout = NULL;
  1836. async = 0;
  1837. callback = 0;
  1838. virt = 0;
  1839. constfunc = 0;
  1840. }
  1841. ProcInfo::~ProcInfo()
  1842. {
  1843. if (name)
  1844. free(name);
  1845. if (conntimeout)
  1846. free(conntimeout);
  1847. if (calltimeout)
  1848. free(calltimeout);
  1849. delete rettype;
  1850. delete params;
  1851. delete next;
  1852. }
  1853. void ProcInfo::out_clarion_parameter_list()
  1854. {
  1855. outs("(");
  1856. ParamInfo * p=params;
  1857. while (p) {
  1858. p->out_clarion_parameter();
  1859. p = p->next;
  1860. if (p)
  1861. outs(", ");
  1862. }
  1863. outs(")");
  1864. }
  1865. void ProcInfo::out_clarion_method()
  1866. {
  1867. outf("%-15s PROCEDURE",xlat(name));
  1868. out_clarion_parameter_list();
  1869. if (rettype)
  1870. {
  1871. outs(",");
  1872. rettype->out_clarion_type(true);
  1873. }
  1874. if (isSCM)
  1875. outs(",PROC\n");
  1876. else
  1877. outs(",PASCAL\n");
  1878. }
  1879. void ProcInfo::out_method(const char *classpfx, int omitvirt)
  1880. {
  1881. if (virt&&!omitvirt)
  1882. {
  1883. if (callback)
  1884. outf("HRPCvirtualcallback ");
  1885. else
  1886. outf("virtual ");
  1887. }
  1888. if (rettype==NULL)
  1889. outs("void");
  1890. else
  1891. rettype->out_type();
  1892. if (classpfx)
  1893. outf(" %s::%s",classpfx,name);
  1894. else
  1895. outf(" %s",name);
  1896. out_parameter_list("");
  1897. if (constfunc)
  1898. {
  1899. if (isSCM)
  1900. outf(" const");
  1901. else
  1902. outf(" /* const (omitted by HIDL) */");
  1903. }
  1904. if ((virt==2)&&!omitvirt)
  1905. {
  1906. if (isSCM)
  1907. outf(" = 0");
  1908. else
  1909. outf(" HRPCpure%s", callback ? "callback" : "");
  1910. }
  1911. }
  1912. void ProcInfo::out_parameter_list(const char *pfx,int forclarion)
  1913. {
  1914. outs("(");
  1915. ParamInfo * p = params;
  1916. while (p)
  1917. {
  1918. p->out_parameter(pfx, forclarion);
  1919. p = p->next;
  1920. if (p)
  1921. outs(", ");
  1922. }
  1923. outs(")");
  1924. }
  1925. void ProcInfo::write_body_method_structs2(const char * modname)
  1926. {
  1927. // buffer structure
  1928. outf("struct HRPC_d_%s__%s\n{\n",modname,name);
  1929. ParamInfo *p;
  1930. lastin=NULL;
  1931. firstin=NULL;
  1932. ForEachParam(this,p,0,0)
  1933. p->flags &= ~PF_SIMPLE;
  1934. size_t align=0;
  1935. int dummy = 0;
  1936. ForEachParam(this,p,PF_IN,PF_OUT|PF_REF|PF_PTR|PF_VARSIZE) {
  1937. p->flags |= PF_SIMPLE;
  1938. lastin = p;
  1939. if (!firstin)
  1940. firstin = p;
  1941. size_t a=p->typesizealign(align);
  1942. if (a>0) {
  1943. dummy++;
  1944. if (a>1)
  1945. outf("\tchar __dummy%d[%u];\n",dummy,(unsigned)a);
  1946. else
  1947. outf("\tchar __dummy%d;\n",dummy);
  1948. }
  1949. p->write_body_struct_elem(0);
  1950. }
  1951. if (align>0) {
  1952. dummy++;
  1953. outf("\tchar _dummy%d[%u];\n",dummy,(unsigned)(4-align));
  1954. align = 0;
  1955. }
  1956. ForEachParam(this,p,PF_IN,PF_OUT|PF_SIMPLE) {
  1957. p->write_body_struct_elem(1);
  1958. }
  1959. ForEachParam(this,p,PF_IN|PF_OUT,PF_SIMPLE) {
  1960. p->write_body_struct_elem(1);
  1961. }
  1962. ForEachParam(this,p,PF_OUT,PF_IN|PF_SIMPLE) {
  1963. p->write_body_struct_elem(1);
  1964. }
  1965. if (rettype) {
  1966. rettype->typesizealign(align);
  1967. rettype->write_body_struct_elem(0);
  1968. if (align>0) {
  1969. dummy++;
  1970. outf("\tchar _dummy%d[%u];\n",dummy,(unsigned)(4-align));
  1971. align = 0;
  1972. }
  1973. }
  1974. int swapp=write_body_swapparam();
  1975. write_body_pushparam(swapp);
  1976. write_body_popparam(swapp);
  1977. if (!async) {
  1978. write_body_pushreturn();
  1979. write_body_popreturn();
  1980. }
  1981. // now constructors
  1982. outf("\tHRPC_d_%s__%s() {}\n",modname,name);
  1983. if (params) {
  1984. outf("\tHRPC_d_%s__%s",modname,name);
  1985. out_parameter_list("_");
  1986. outs(": ");
  1987. ForEachParam(this,p,0,0) {
  1988. outf("%s(",p->name);
  1989. if (p->flags&PF_REF) {
  1990. outs("&");
  1991. }
  1992. else if ((p->flags&(PF_PTR&PF_CONST))==(PF_PTR&PF_CONST)) {
  1993. p->write_param_convert();
  1994. }
  1995. outf("_%s)",p->name);
  1996. if (p->next)
  1997. outs(", ") ;
  1998. }
  1999. outs("\n\t{\n");
  2000. outs("\t};");
  2001. }
  2002. outs("\n};\n");
  2003. }
  2004. void ProcInfo::write_body_popparam(int swapp)
  2005. {
  2006. outs("\tvoid popparams(HRPCbuffer &_b)\n\t{\n");
  2007. if (lastin) {
  2008. outf("\t\t_b.read(&%s,",firstin->name);
  2009. write_head_size();
  2010. outs(");\n");
  2011. }
  2012. int needensure=0;
  2013. ParamInfo *p;
  2014. ForEachParam(this,p,PF_OUT,PF_IN|PF_SIMPLE) {
  2015. if (needensure) {
  2016. outs("\t\t\t+");
  2017. }
  2018. else {
  2019. outs("\t\t_b.ensure(\n");
  2020. outs("\t\t\t");
  2021. needensure = 1;
  2022. }
  2023. if ((p->flags&PF_VARSIZE)&&!(INDIRECTSIZE(p))) {
  2024. outf("(%s)\n",p->bytesize());
  2025. }
  2026. else {
  2027. outf("sizeof(*%s)\n",p->name);
  2028. }
  2029. }
  2030. if (needensure) {
  2031. outs("\t\t);\n");
  2032. }
  2033. ForEachParam(this,p,PF_OUT,PF_IN|PF_SIMPLE|PF_VARSIZE|PF_STRING) {
  2034. outf("\t\t%s = ",p->name);
  2035. p->write_param_convert();
  2036. outf("_b.writeptr(sizeof(*%s));\n",p->name);
  2037. }
  2038. ForEachParam(this,p,PF_OUT|PF_STRING,0) {
  2039. outf("\t\t%s = ",p->name);
  2040. p->write_param_convert();
  2041. outf("_b.writeptr(sizeof(*%s));\n",p->name);
  2042. outf("\t\t*%s = 0;\n",p->name);
  2043. }
  2044. ForEachParam(this,p,PF_IN,PF_SIMPLE|PF_VARSIZE|PF_STRING) {
  2045. outf("\t\t%s = ",p->name);
  2046. p->write_param_convert();
  2047. outf("_b.readptr(sizeof(*%s));\n",p->name);
  2048. outf("\t\t\t//_b.readptrrev(sizeof(*%s));\n",p->name);
  2049. }
  2050. ForEachParam(this,p,PF_IN|PF_STRING,PF_SIMPLE|PF_VARSIZE) {
  2051. outf("\t\t%s = _b.readstrptr();\n",p->name);
  2052. }
  2053. // now dynamic sizes
  2054. ForEachParam(this,p,PF_VARSIZE|PF_IN,0) {
  2055. outf("\t\t%s = ",p->name);
  2056. p->write_param_convert();
  2057. if (INDIRECTSIZE(p)) {
  2058. // should handle size_t* as well as ref
  2059. outs("_b.readptr(sizeof");
  2060. p->write_param_convert();
  2061. outs(")\n");
  2062. }
  2063. else {
  2064. outf("_b.readptr(%s);\n",p->bytesize());
  2065. }
  2066. }
  2067. ForEachParam(this,p,PF_OUT|PF_VARSIZE,PF_IN|PF_SIMPLE) {
  2068. outf("\t\t%s = ",p->name);
  2069. p->write_param_convert();
  2070. outs("_b.writeptr(");
  2071. if ((p->flags&PF_VARSIZE)&&!(INDIRECTSIZE(p))) {
  2072. outf("%s);\n",p->bytesize());
  2073. }
  2074. else {
  2075. outf("sizeof(*%s));\n",p->name);
  2076. }
  2077. }
  2078. if (swapp)
  2079. outs("\t\t//swapparams();\n");
  2080. outs("\t}\n\n");
  2081. }
  2082. void ProcInfo::write_body_popreturn()
  2083. {
  2084. if (!async) {
  2085. outs("\tvoid popreturn(HRPCbuffer &_b)\n\t{\n");
  2086. ParamInfo *p;
  2087. ForEachParam(this,p,PF_OUT,PF_SIMPLE|PF_VARSIZE|PF_RETURN|PF_STRING) {
  2088. outf("\t\t_b.read(%s,sizeof(*%s));\n",p->name,p->name);
  2089. }
  2090. ForEachParam(this,p,PF_OUT|PF_STRING,0) {
  2091. outf("\t\t*%s = _b.readstrdup();\n",p->name);
  2092. }
  2093. // now dynamic sizes
  2094. ForEachParam(this,p,PF_VARSIZE|PF_OUT,0) {
  2095. if (INDIRECTSIZE(p)) {
  2096. outf("\t\t*%s = ",p->name);
  2097. p->write_param_convert(1);
  2098. outf("malloc(%s);\n",p->bytesize(1));
  2099. outf("\t\t_b.read(*%s,%s);\n",p->name,p->bytesize(1));
  2100. }
  2101. else {
  2102. outf("\t\t_b.read(%s,%s);\n",p->name,p->bytesize());
  2103. }
  2104. }
  2105. p = rettype;
  2106. if (p) {
  2107. if ((p->flags&(PF_PTR|PF_STRING))==(PF_PTR|PF_STRING)) {
  2108. outf("\t\t%s = _b.readstrdup();\n",p->name);
  2109. }
  2110. else if (p->flags&PF_PTR) {
  2111. outf("\t\t%s = ",p->name);
  2112. p->write_param_convert();
  2113. outf("malloc(%s);\n",p->bytesize(1));
  2114. outf("\t\t_b.read(%s,%s);\n",p->name,p->bytesize(1));
  2115. }
  2116. else {
  2117. outf("\t\t_b.read(&%s,sizeof(%s));\n",p->name,p->name);
  2118. }
  2119. }
  2120. outs("\t}\n\n");
  2121. }
  2122. }
  2123. int ProcInfo::write_body_swapparam()
  2124. {
  2125. int ret=0;
  2126. ParamInfo *p;
  2127. ForEachParam(this,p,PF_IN|PF_SIMPLE,PF_VARSIZE|PF_STRING) {
  2128. if(p->simpleneedsswap()) {
  2129. if (!ret) {
  2130. outs("\tvoid swapparams()\n\t{\n");
  2131. ret = 1;
  2132. }
  2133. outf("\t\t_WINREV%d(%s);\n",type_size[p->kind],p->name);
  2134. }
  2135. }
  2136. if (ret)
  2137. outs("\t}\n\n");
  2138. return ret;
  2139. }
  2140. void ProcInfo::write_body_pushparam(int swapp)
  2141. {
  2142. outs("\tvoid pushparams(HRPCbuffer &_b)\n\t{\n");
  2143. if (swapp)
  2144. outs("\t\t//swapparams();\n");
  2145. if (lastin) {
  2146. outf("\t\t_b.write(&%s,",firstin->name);
  2147. write_head_size();
  2148. outs(");\n");
  2149. }
  2150. ParamInfo *p;
  2151. ForEachParam(this,p,PF_IN,PF_SIMPLE|PF_VARSIZE|PF_STRING) {
  2152. if (p->simpleneedsswap()) {
  2153. outf("\t\t//_b.writerev(%s,sizeof(*%s));\n",p->name,p->name);
  2154. outf("\t\t_b.write(%s,sizeof(*%s));\n",p->name,p->name);
  2155. }
  2156. else
  2157. outf("\t\t_b.write(%s,sizeof(*%s));\n",p->name,p->name);
  2158. }
  2159. ForEachParam(this,p,PF_IN|PF_STRING,PF_SIMPLE|PF_VARSIZE) {
  2160. outf("\t\t_b.writestr(%s);\n",p->name);
  2161. }
  2162. // now dynamic sizes
  2163. ForEachParam(this,p,PF_VARSIZE|PF_IN,0) {
  2164. if (INDIRECTSIZE(p)) {
  2165. // should handle size_t* as well as ref
  2166. outf("\t\t_b.write(%s,%s);\n",p->name,p->bytesize());
  2167. }
  2168. else {
  2169. outf("\t\t_b.write(%s,%s);\n",p->name,p->bytesize());
  2170. }
  2171. }
  2172. outs("\t}\n\n");
  2173. }
  2174. void ProcInfo::write_body_pushreturn()
  2175. {
  2176. if (!async) {
  2177. outs("\tvoid pushreturn(HRPCbuffer &_b)\n\t{\n");
  2178. ParamInfo *p;
  2179. ForEachParam(this,p,PF_OUT,PF_SIMPLE|PF_VARSIZE|PF_STRING) {
  2180. outf("\t\t_b.write(%s,sizeof(*%s));\n",p->name,p->name);
  2181. }
  2182. ForEachParam(this,p,PF_OUT|PF_STRING,0) {
  2183. outf("\t\t_b.writestr(*%s);\n",p->name);
  2184. outf("\t\tfree(*%s);\n",p->name);
  2185. }
  2186. // now dynamic sizes
  2187. ForEachParam(this,p,PF_VARSIZE|PF_OUT,0) {
  2188. if (INDIRECTSIZE(p)) {
  2189. // should handle size_t* as well as ref
  2190. outf("\t\t_b.write(*%s,%s);\n",p->name,p->bytesize(1));
  2191. outf("\t\tfree(*%s);\n",p->name);
  2192. }
  2193. else {
  2194. outf("\t\t_b.write(%s,%s);\n",p->name,p->bytesize());
  2195. }
  2196. }
  2197. p = rettype;
  2198. if (p) {
  2199. if ((p->flags&(PF_PTR|PF_STRING))==(PF_PTR|PF_STRING)) {
  2200. outf("\t\t_b.writestr(%s);\n",p->name);
  2201. outf("\t\tfree(%s);\n",p->name);
  2202. }
  2203. else if (p->flags&PF_PTR) {
  2204. outf("\t\t_b.write(%s,%s);\n",p->name,p->bytesize(1));
  2205. outf("\t\tfree(%s);\n",p->name);
  2206. }
  2207. else {
  2208. outf("\t\t_b.write(&%s,sizeof(%s));\n",p->name,p->name);
  2209. }
  2210. }
  2211. outs("\t}\n\n");
  2212. }
  2213. }
  2214. void ProcInfo::write_head_size()
  2215. // used for simple types only at the head of the packet
  2216. {
  2217. if (lastin) {
  2218. char sz[2048];
  2219. sz[0] = 0;
  2220. size_t sza=0;
  2221. ParamInfo *p=params;
  2222. ParamInfo *lp=NULL;
  2223. while (1) {
  2224. if (p->flags&PF_SIMPLE) {
  2225. lp = p;
  2226. }
  2227. if(p==lastin)
  2228. break;
  2229. p = p->next;
  2230. }
  2231. if (lp==NULL)
  2232. outs("0");
  2233. else if (lp!=firstin)
  2234. outf("sizeof(%s)+(byte *)&%s-(byte *)&%s",lp->name,lp->name,firstin->name);
  2235. else
  2236. outf("sizeof(%s)",firstin->name);
  2237. }
  2238. else
  2239. outs("0");
  2240. }
  2241. //-------------------------------------------------------------------------------------------------------------
  2242. // class ApiInfo
  2243. ApiInfo::ApiInfo(const char *n)
  2244. {
  2245. name = NULL;
  2246. group = strdup(n);
  2247. proc = NULL;
  2248. next = NULL;
  2249. }
  2250. ApiInfo::~ApiInfo()
  2251. {
  2252. if (name)
  2253. free(name);
  2254. if (proc)
  2255. delete proc;
  2256. if (group)
  2257. free(group);
  2258. delete next;
  2259. }
  2260. void ApiInfo::write_header_method()
  2261. {
  2262. ProcInfo *pi = proc;
  2263. if (!pi->callback)
  2264. {
  2265. outf("extern \"C\" %s_API ", group);
  2266. pi->rettype->out_type();
  2267. outf(" %s", pi->name);
  2268. pi->out_parameter_list("");
  2269. outs(";\n");
  2270. }
  2271. }
  2272. void ApiInfo::write_clarion_include_method()
  2273. {
  2274. ProcInfo *pi = proc;
  2275. if (!pi->callback)
  2276. {
  2277. outf(" %s ",xlat(pi->name));
  2278. pi->out_clarion_parameter_list();
  2279. if (pi->rettype)
  2280. {
  2281. outs(",");
  2282. pi->rettype->out_clarion_type(true);
  2283. }
  2284. ParamInfo *pa;
  2285. unsigned sizeOfParms=0;
  2286. ForEachParam(pi, pa, 0, 0)
  2287. {
  2288. if (pa->flags&(PF_PTR|PF_REF))
  2289. sizeOfParms+=4;
  2290. else
  2291. sizeOfParms+=type_size[pa->kind];
  2292. }
  2293. outf(", pascal, raw, name('_%s@%d')\n", pi->name,sizeOfParms);
  2294. }
  2295. }
  2296. //-------------------------------------------------------------------------------------------------------------
  2297. // class ModuleInfo
  2298. ModuleInfo::ModuleInfo(const char *n)
  2299. {
  2300. name = strdup(n);
  2301. base = NULL;
  2302. version = 0;
  2303. procs = NULL;
  2304. next = NULL;
  2305. isSCMinterface=false;
  2306. }
  2307. ModuleInfo::~ModuleInfo()
  2308. {
  2309. free(name);
  2310. if (base)
  2311. free(base);
  2312. delete procs;
  2313. delete next;
  2314. }
  2315. void ModuleInfo::write_body_class()
  2316. {
  2317. outf("// class %s \n\n",name);
  2318. outf("static struct HRPCmoduleid _id_%s = { { ",name);
  2319. char *mn = name;
  2320. for (int i=0;i<8;i++)
  2321. {
  2322. if (i)
  2323. outs(", ");
  2324. if (*mn) {
  2325. outf("'%c'",*mn);
  2326. mn++;
  2327. }
  2328. else
  2329. outs("0");
  2330. }
  2331. outf("}, %d };\n\n",version);
  2332. int fn=0;
  2333. for (ProcInfo *pi=procs; pi; pi=pi->next)
  2334. {
  2335. fn++;
  2336. pi->write_body_method_structs2(name);
  2337. }
  2338. outs("\n");
  2339. outf("%s::%s() { _id = &_id_%s; }\n\n",name,name,name);
  2340. outf("#ifdef LOCAL_%s // Stub(%s):\n\n",name,name);
  2341. write_body_class_stub(0);
  2342. write_body_class_proxy(1);
  2343. outf("#else // Proxy(%s):\n\n",name);
  2344. write_body_class_proxy(0);
  2345. write_body_class_stub(1);
  2346. outf("\n#endif // end class %s\n",name);
  2347. }
  2348. void ModuleInfo::write_body_class_proxy(int cb)
  2349. {
  2350. int fn = 0;
  2351. ProcInfo *pi;
  2352. for (pi=procs; pi; pi=pi->next) {
  2353. fn++;
  2354. if (cb!=pi->callback)
  2355. continue;
  2356. pi->out_method(name,true);
  2357. outs("\n{\n");
  2358. if (pi->callback) {
  2359. outs("\tHRPCcallframe _callframe(&_server->Sync(),cbbuff);\n");
  2360. }
  2361. else {
  2362. outs("\tHRPCcallframe _callframe(sync,inbuff);\n");
  2363. }
  2364. outf("\tHRPC_d_%s__%s _params",name,pi->name);
  2365. if (pi->params) {
  2366. outs("(");
  2367. ParamInfo *p;
  2368. ForEachParam(pi,p,0,0) {
  2369. outf("%s",p->name);
  2370. if (p->next)
  2371. outs(", ");
  2372. }
  2373. outs(")");
  2374. }
  2375. outs(";\n");
  2376. if (pi->conntimeout&&*pi->conntimeout) {
  2377. outf("\tTryConnect(%s,false);\n",pi->conntimeout);
  2378. }
  2379. if (pi->calltimeout&&*pi->calltimeout) {
  2380. outf("\tSetCallTimeLimit(%s);\n",pi->calltimeout);
  2381. }
  2382. if (pi->callback) {
  2383. outs("\t_params.pushparams(cbbuff);\n");
  2384. outf("\t_callbackproxy(_callframe,%d);\n",fn);
  2385. if (!pi->async)
  2386. outs("\t_params.popreturn(cbbuff);\n");
  2387. }
  2388. else {
  2389. outs("\t_params.pushparams(inbuff);\n");
  2390. outf("\t_proxy(_callframe,%d);\n",fn);
  2391. if (!pi->async)
  2392. outs("\t_params.popreturn(inbuff);\n");
  2393. }
  2394. if (pi->rettype) {
  2395. outf("\treturn _params.%s;\n",RETURNNAME);
  2396. }
  2397. outs("}\n\n");
  2398. }
  2399. outs("\n\n");
  2400. }
  2401. void ModuleInfo::write_body_class_stub(int cb)
  2402. {
  2403. outf("void %s::_%sstub(HRPCbuffer &_b,HRPCbuffer &_br,int fn)\n{\n",name,cb?"callback":"");
  2404. int fn=0;
  2405. int switchdone = 0;
  2406. ProcInfo *pi;
  2407. for (pi=procs; pi; pi=pi->next) {
  2408. fn++;
  2409. if (cb!=pi->callback)
  2410. continue;
  2411. if (!switchdone) {
  2412. outs("\tswitch(fn) {\n");
  2413. switchdone = 1;
  2414. }
  2415. outf("\tcase %d: {\n",fn);
  2416. outf("\t\t\tHRPC_d_%s__%s _params;\n",name,pi->name);
  2417. outs("\t\t\t_params.popparams(_b);\n");
  2418. if (pi->async) {
  2419. outs("\t\t\t_returnasync(_br);\n");
  2420. }
  2421. outs("\t\t\t");
  2422. if (pi->rettype) {
  2423. outf("_params.%s = ",RETURNNAME);
  2424. }
  2425. outf("%s(",pi->name);
  2426. ParamInfo *p;
  2427. ForEachParam(pi,p,0,0) {
  2428. if (p->flags&PF_REF)
  2429. outs("*");
  2430. outf("_params.%s",p->name);
  2431. if (p->next)
  2432. outs(", ");
  2433. }
  2434. outs(");\n");
  2435. if (!pi->async) {
  2436. outs("\t\t\t_returnOK(_br);\n");
  2437. outs("\t\t\t_params.pushreturn(_br);\n");
  2438. }
  2439. outs("\t\t\tbreak;\n");
  2440. outs("\t\t}\n");
  2441. }
  2442. if (switchdone) {
  2443. outs("\t}\n");
  2444. }
  2445. outs("}\n\n");
  2446. }
  2447. void ModuleInfo::write_clarion_include_module()
  2448. {
  2449. if (isSCM) {
  2450. char _name[256];
  2451. toClaInterface(_name, name);
  2452. if (base) {
  2453. char _base[256];
  2454. toClaInterface(_base, base);
  2455. outf("%s INTERFACE(%s),COM\n", _name, _base);
  2456. }
  2457. else
  2458. outf("%s INTERFACE,COM\n", _name);
  2459. }
  2460. else
  2461. outf("HRPCI_%s INTERFACE(HRPCI_Clarion_Module)\n",name);
  2462. ProcInfo *pi;
  2463. for (pi=procs; pi; pi=pi->next) {
  2464. if (pi->callback)
  2465. continue;
  2466. outf("%-15s PROCEDURE",xlat(pi->name));
  2467. pi->out_clarion_parameter_list();
  2468. if (pi->rettype) {
  2469. outs(",");
  2470. pi->rettype->out_clarion_type(true);
  2471. }
  2472. if (isSCM)
  2473. outs(",PROC\n");
  2474. else
  2475. outs(",PASCAL\n");
  2476. }
  2477. outs("END\n\n");
  2478. }
  2479. void ModuleInfo::write_clarion_scm_stub_class()
  2480. {
  2481. outf("// clarion interface stub for %s \n",name);
  2482. outf("class SCMCLWSTUB_%s: public SCMStubBase, implements %s // interface\n",name,name);
  2483. outf("\t%s &_o;\n",name);
  2484. outf("public:\n");
  2485. outf("\tIMPLEMENT_SCMSTUBBASE\n");
  2486. outf("\tSCMCLW_%s(%s *_if) : SCMStubBase(_if), _o(*LINK(_if)) { } \n",name,name);
  2487. outf("\t~SCMCLW_%s() { _o.Release(); } \n",name);
  2488. ProcInfo *pi;
  2489. for (pi=procs; pi; pi=pi->next) {
  2490. if (pi->callback)
  2491. continue;
  2492. outs("\t");
  2493. if (pi->rettype==NULL)
  2494. {
  2495. outs("void");
  2496. }
  2497. else
  2498. pi->rettype->out_type();
  2499. outf(" _stdcall %s",pi->name);
  2500. pi->out_parameter_list("",1);
  2501. outs("\n");
  2502. outs("\t{\n");
  2503. outs("\t\tSCMCLW_INTRO;\n");
  2504. outf("#ifdef SCMCLW_INTRO_%s_%s;\n",name,pi->name);
  2505. outf("\t\tSCMCLW_INTRO_%s_%s;\n",name,pi->name);
  2506. outs("#endif\n");
  2507. if (pi->rettype) {
  2508. outs("\t");
  2509. pi->rettype->write_body_struct_elem(0);
  2510. outs("\t\t_return = ");
  2511. }
  2512. else
  2513. outs("\t\t");
  2514. outf("_o.%s(",pi->name);
  2515. ParamInfo *p;
  2516. ForEachParam(pi,p,0,0) {
  2517. outf("%s",p->name);
  2518. if (p->next)
  2519. outs(", ");
  2520. }
  2521. outs(");\n");
  2522. outf("#ifdef SCMCLW_OUTRO_%s_%s;\n",name,pi->name);
  2523. outf("\t\tSCMCLW_OUTRO_%s_%s;\n",name,pi->name);
  2524. outs("#endif\n");
  2525. outs("\t\tSCMCLW_OUTRO;\n");
  2526. if (pi->rettype) {
  2527. outs("\t\treturn _return;");
  2528. }
  2529. outs("\t}\n");
  2530. }
  2531. outs("};\n");
  2532. }
  2533. void ModuleInfo::write_clarion_interface_class()
  2534. {
  2535. outs("extern \"C\" {\n\n");
  2536. outs("\n");
  2537. outf("// clarion interface class CIC_%s \n",name);
  2538. outf("struct HRPCI_%s: public HRPCI_Clarion_Module // interface\n",name);
  2539. ProcInfo *pi;
  2540. outs("{\n");
  2541. for (pi=procs; pi; pi=pi->next) {
  2542. if (pi->callback)
  2543. continue;
  2544. outs("\tvirtual ");
  2545. if (pi->rettype==NULL)
  2546. {
  2547. outs("void");
  2548. }
  2549. else
  2550. pi->rettype->out_type();
  2551. outf(" _stdcall %s",pi->name);
  2552. pi->out_parameter_list("",1);
  2553. outs("=0;\n");
  2554. }
  2555. outs("};\n");
  2556. outf("#ifndef LOCAL_%s\n\n",name);
  2557. outf("class CIC_%s : public HRPCI_%s\n",name,name);
  2558. outs("{\n");
  2559. outs("public:\n");
  2560. outf("\t%s _o;\n",name);
  2561. outs("\tunsigned xxcount;\n");
  2562. for (pi=procs; pi; pi=pi->next) {
  2563. if (pi->callback)
  2564. continue;
  2565. outs("\t");
  2566. if (pi->rettype==NULL)
  2567. {
  2568. outs("void");
  2569. }
  2570. else
  2571. pi->rettype->out_type();
  2572. outf(" _stdcall %s",pi->name);
  2573. pi->out_parameter_list("",1);
  2574. outs("\n");
  2575. outs("\t{\n");
  2576. outs("\t\t");
  2577. if (pi->rettype) {
  2578. outs("return ");
  2579. }
  2580. outf("_o.%s(",pi->name);
  2581. ParamInfo *p;
  2582. ForEachParam(pi,p,0,0) {
  2583. outf("%s",p->name);
  2584. if (p->next)
  2585. outs(", ");
  2586. }
  2587. outs(");\n");
  2588. outs("\t}\n");
  2589. }
  2590. outf("\tCIC_%s() { xxcount = 0; }\n",name);
  2591. outf("\tvoid _stdcall Link() const { ++const_cast<CIC_%s*>(this)->xxcount; }\n", name);
  2592. outf("\tint _stdcall Release() const { \n\t\tCIC_%s* ths = const_cast<CIC_%s*>(this);\n\t\tif (ths->xxcount == 0) { delete ths; return 1; }\n\t\t--ths->xxcount;\n\t\treturn 0;\n\t}\n",name,name);
  2593. outs("\tvoid _stdcall FreeMem(void *p) { free(p); }\n");
  2594. outs("};\n");
  2595. outf("CIC_%s* PASCAL HRPC_Make_%s(HRPCI_Clarion_Transport *t)\n",name,name);
  2596. outs("{\n");
  2597. outf("\tCIC_%s *ret=new CIC_%s;\n",name,name);
  2598. outs("\tret->_o.UseTransport(t->GetTransport());\n");
  2599. outs("\treturn ret;\n");
  2600. outs("}\n");
  2601. outs("#endif\n");
  2602. outs("}\n");
  2603. }
  2604. void ModuleInfo::write_define()
  2605. {
  2606. outf("#define LOCAL_%s // implementation of %s\n",name,name);
  2607. }
  2608. void ModuleInfo::write_example_module()
  2609. {
  2610. outf("void %s_Server()\n",name);
  2611. outs("{\n");
  2612. outs("\tHRPCserver server(MakeTcpTransport(NULL,PORTNO)); // PORTNO TBD\n");
  2613. outf("\t%s stub;\n",name);
  2614. outs("\tserver.AttachStub(&stub); // NB a server can service more than one module\n");
  2615. outs("\tserver.Listen();\n");
  2616. outs("}\n\n");
  2617. ProcInfo *pi;
  2618. for (pi=procs; pi; pi=pi->next) {
  2619. pi->out_method(name,true);
  2620. outs("\n{\n");
  2621. outf("\t // TBD\n");
  2622. if (pi->rettype) {
  2623. outs("\treturn TBD;\n");
  2624. }
  2625. outs("}\n\n");
  2626. }
  2627. }
  2628. void ModuleInfo::write_header_class()
  2629. {
  2630. int hasvirts = 0;
  2631. ProcInfo *pi;
  2632. for (pi=procs; pi; pi=pi->next) {
  2633. if (pi->virt) {
  2634. hasvirts = 1;
  2635. break;
  2636. }
  2637. }
  2638. if (isSCM) {
  2639. if (base)
  2640. outf("interface %s : extends %s\n",name,base);
  2641. else
  2642. outf("interface %s\n",name);
  2643. outs("{\n");
  2644. for (pi=procs; pi; pi=pi->next) {
  2645. outs("\t");
  2646. pi->out_method();
  2647. outs(";\n");
  2648. }
  2649. outs("};\n");
  2650. }
  2651. else {
  2652. outf("#ifdef LOCAL_%s\n",name);
  2653. outf("#define %s STUB_%s\n",name,name);
  2654. if (hasvirts) {
  2655. outs("#define HRPCvirtual virtual\n");
  2656. outs("#define HRPCpure =0\n");
  2657. outs("#define HRPCvirtualcallback\n");
  2658. outs("#define HRPCpurecallback\n");
  2659. }
  2660. outf("class %s : public HRPCstub\n",name);
  2661. outs("#else\n");
  2662. if (hasvirts) {
  2663. outs("#define HRPCvirtual\n");
  2664. outs("#define HRPCpure\n");
  2665. outs("#define HRPCvirtualcallback virtual\n");
  2666. outs("#define HRPCpurecallback =0\n");
  2667. }
  2668. outf("class %s : public HRPCmodule\n",name);
  2669. outs("#endif\n");
  2670. outs("{\npublic:\n");
  2671. outf("\t%s();\n",name);
  2672. for (pi=procs; pi; pi=pi->next) {
  2673. outs("\t");
  2674. pi->out_method();
  2675. outs(";\n");
  2676. }
  2677. outf("private:\n");
  2678. outf("#ifdef LOCAL_%s\n",name);
  2679. outf("\tvoid _stub(HRPCbuffer &_b,HRPCbuffer &_rb,int fn);\n");
  2680. outs("#else\n");
  2681. outf("\tvoid _callbackstub(HRPCbuffer &_b,HRPCbuffer &_rb,int fn);\n");
  2682. outs("#endif\n");
  2683. if (hasvirts) {
  2684. outs("#undef HRPCvirtual\n");
  2685. outs("#undef HRPCpure\n");
  2686. outs("#undef HRPCvirtualcallback\n");
  2687. outs("#undef HRPCpurecallback\n");
  2688. }
  2689. outs("};\n");
  2690. }
  2691. }
  2692. //-------------------------------------------------------------------------------------------------------------
  2693. // class EspMessageInfo
  2694. void EspMessageInfo::write_esp_ipp()
  2695. {
  2696. ParamInfo *pi;
  2697. const char *parent = getParentName();
  2698. if (espm_type_ == espm_enum)
  2699. {
  2700. //const char* defaultValue = getParams()->getMetaString("enum",NULL); // first enum item
  2701. outf("class CX%s : public SoapEnumParamNew<C%s>\n",name_,name_);
  2702. outf("{\n");
  2703. outs("public:\n");
  2704. outf("\tCX%s(nilBehavior nilB) : SoapEnumParamNew<C%s>(nilB)\n", name_, name_);
  2705. outf("\t{ doInit(); }\n");
  2706. outf("\tCX%s(C%s defvalue_) : SoapEnumParamNew<C%s>(defvalue_)\n", name_, name_, name_);
  2707. outf("\t{ doInit(); }\n");
  2708. outf("\tCX%s(const char* defvalue_) : SoapEnumParamNew<C%s>()\n", name_, name_);
  2709. outf("\t{ doInit(); setDefaultValue(defvalue_); }\n");
  2710. // getXsdDefinition
  2711. outs("\tstatic void getXsdDefinition(IEspContext &context, CHttpRequest* request, StringBuffer &schema, BoolHash &added)\n");
  2712. outs("\t{ getSharedInstance().getXsdDefinitionInternal(context,request,schema,added); }\n");
  2713. // getMapInfo()
  2714. outs("\tstatic void getMapInfo(IMapInfo& info, BoolHash& added) { getSharedInstance().getMapInfo_(info,added); }\n\n");
  2715. outf("\tstatic const char* stringOf(C%s val) { return getSharedInstance().toString(val); }\n\n",name_);
  2716. outf("\tstatic C%s enumOf(const char* s) { return getSharedInstance().toEnum(s); }\n\n",name_);
  2717. outf("static const char *queryXsdElementName() { return \"%s\"; }\n", name_);
  2718. // internal: getSharedInstance()
  2719. outs("private:\n");
  2720. outf("\tstatic CX%s& getSharedInstance() { static CX%s instance(nilIgnore); return instance; }\n", name_, name_);
  2721. // TODO: getMapInfo_() internal implementation
  2722. outs("\tvoid getMapInfo_(IMapInfo& info, BoolHash& added) { }\n");
  2723. // handle descriptions
  2724. {
  2725. outs("\tvoid getXsdDefinitionInternal(IEspContext &context, CHttpRequest* request, StringBuffer &schema, BoolHash &added)\n");
  2726. bool hasDesc = false;
  2727. for (pi = getParams(); pi!=NULL; pi=pi->next)
  2728. {
  2729. const char* desc = pi->getMetaString("desc",NULL);
  2730. if (desc) { hasDesc = true; break; }
  2731. }
  2732. if (hasDesc)
  2733. {
  2734. outs("\t{\n\t\tconst char* descriptions [] = {");
  2735. for (pi = getParams(); pi!=NULL; pi=pi->next)
  2736. {
  2737. const char* desc = pi->getMetaString("desc",NULL);
  2738. outf("%s,", desc ? desc : "NULL");
  2739. }
  2740. outs("};\n");
  2741. outs("\t\tgetXsdDefinition_(context,request,schema,added,descriptions);\n\t}\n");
  2742. }
  2743. else
  2744. outf("\t{ getXsdDefinition_(context,request,schema,added,NULL); }\n");
  2745. }
  2746. outf("\tvoid doInit()\n");
  2747. outs("\t{\n");
  2748. outs("\t\tstatic const char* inits[] = {");
  2749. for (pi = getParams(); pi!=NULL; pi=pi->next)
  2750. {
  2751. if (strcmp(parent,"string")==0)
  2752. {
  2753. const char* def = pi->getMetaString("enum",NULL);
  2754. outf("%s", def);
  2755. }
  2756. else if (strcmp(parent,"int")==0 || strcmp(parent,"short")==0)
  2757. {
  2758. int def = pi->getMetaInt("enum");
  2759. outf("\"%d\"",def);
  2760. }
  2761. else if (strcmp(parent,"double")==0 || strcmp(parent,"float")==0)
  2762. {
  2763. double def = pi->getMetaDouble("enum");
  2764. outf("\"%g\"",def);
  2765. }
  2766. else
  2767. throw "Unhandled base type";
  2768. outs(",");
  2769. }
  2770. outs("NULL};\n");
  2771. outf("\t\tinit(\"%s\",\"%s\",inits);\n",name_,parent);
  2772. outs("\t}\n");
  2773. outs("};\n\n");
  2774. // array
  2775. #if 0
  2776. //outf("MAKEValueArray(C%s, %sArray);\n\n", name_, name_);
  2777. outf("inline C%s Array__Member2Param(C%s &src) { return src; }\n", name_, name_);
  2778. outf("inline void Array__Assign(C%s & dest, C%s const & src){ dest = src; }\n", name_, name_);
  2779. outf("inline bool Array__Equal(C%s const & m, C%s const p) { return m==p; }\n", name_, name_);
  2780. outf("inline void Array__Destroy(C%s & /*next* /) { }\n", name_);
  2781. //outf("MAKECopyArrayOf(simple, simple, array)
  2782. outf("MAKEArrayOf(C%s, C%s, %sArray)\n\n", name_,name_,name_);
  2783. //outf("class %sArray : public ArrayOf<C%s, C%s> {};\n\n",name_,name_,name_);
  2784. outs("\n");
  2785. #endif
  2786. return;
  2787. }
  2788. ParamInfo *contentVar=NULL;
  2789. bool removeNil=(getMetaInt("nil_remove", 0)!=0);
  2790. for (pi=getParams();pi!=NULL;pi=pi->next)
  2791. {
  2792. if (pi->getMetaString("http_content", NULL)!=NULL)
  2793. {
  2794. contentVar=pi;
  2795. break;
  2796. }
  2797. }
  2798. const char *baseclass = parent;
  2799. if (!baseclass)
  2800. {
  2801. switch(espm_type_)
  2802. {
  2803. case espm_struct:
  2804. baseclass="SoapComplexType";
  2805. break;
  2806. case espm_request:
  2807. baseclass="SoapRequestBinding";
  2808. break;
  2809. default:
  2810. baseclass="SoapResponseBinding";
  2811. break;
  2812. }
  2813. }
  2814. outf("class C%s : public C%s,\n", name_, baseclass);
  2815. outf(" implements IEsp%s,\n", name_);
  2816. outf(" implements IClient%s\n", name_);
  2817. outs("{\n");
  2818. outs("protected:\n");
  2819. for (pi=getParams();pi!=NULL;pi=pi->next)
  2820. {
  2821. pi->write_esp_declaration();
  2822. }
  2823. if (getMetaInt("element")!=0)
  2824. outs(1, "StringBuffer m_tag_value;\n");
  2825. if (contentVar!=NULL)
  2826. outf("\tStringBuffer m_%s_mimetype;\n", contentVar->name);
  2827. outs("\n\tvoid *m_eventSink = nullptr;\n");
  2828. outs("\n\tIInterface* m_RequestState = nullptr;\n");
  2829. outs("\tStringBuffer m_serviceName;\n");
  2830. outs("\tStringBuffer m_methodName;\n");
  2831. outs("\tStringBuffer m_msgName;\n");
  2832. outs("\n\tlong soap_reqid = 0;\n");
  2833. outs("\tMutex m_mutex;\n");
  2834. outs("public:\n");
  2835. outs("\tIMPLEMENT_IINTERFACE;\n");
  2836. //default constructor
  2837. outf("\n\tC%s(const char *serviceName, const char *bcompat);\n", name_);
  2838. outf("\n\tC%s(const char *serviceName, IRpcMessageBinding *init=NULL);", name_);
  2839. if (espm_type_==espm_struct)
  2840. {
  2841. //Raw message constructor
  2842. //outf("\n\tC%s(const char *serviceName, const char * msg);", name_);
  2843. }
  2844. else
  2845. {
  2846. //rpc message constructor
  2847. outf("\n\tC%s(const char *serviceName, IRpcMessage* rpcmsg);", name_);
  2848. //IProperties constructor
  2849. outf("\n\tC%s(IEspContext* ctx, const char *serviceName, IProperties *params, MapStrToBuf *attachments);", name_);
  2850. }
  2851. if (espm_type_==espm_request)
  2852. outs("\n\tIEspClientRpcSettings &rpc(){return *static_cast<IEspClientRpcSettings*>(this);}\n\n");
  2853. outf("\n\tvirtual const char *getNsURI(){return %s;}\n", getMetaString("ns_uri", "NULL"));
  2854. outf("\n\tvirtual const char *getNsPrefix(){return %s;}\n", getMetaString("ns_var", "NULL"));
  2855. outs("\n\tvirtual const char *getRootName(){return m_msgName.str();}\n");
  2856. outs("\n\tvoid setMsgName(const char *msgname)\n");
  2857. outs("\t{\n");
  2858. outs("\t\tm_msgName.set(msgname);\n");
  2859. outs("\t}\n\n");
  2860. outs("\tstatic const char *queryXsdElementName()\n");
  2861. outs("\t{\n");
  2862. outf("\t\treturn \"%s\";\n", name_);
  2863. outs("\t}\n\n");
  2864. //method ==> getXsdDefinition
  2865. outs("\tstatic StringBuffer &getXsdDefinition(IEspContext &context, CHttpRequest* request, StringBuffer &schema, BoolHash&added, const char *xns=\"xsd\", const char *wsns=\"tns\", unsigned flags=1)\n");
  2866. outs("\t{\n");
  2867. outs("\t\treturn getXsdDefinition(context, request, queryXsdElementName(), schema, added, xns, wsns, flags);\n");
  2868. outs("\t}\n");
  2869. //method ==> getXsdDefinition
  2870. outs("\tstatic StringBuffer &getXsdDefinition(IEspContext &context, CHttpRequest* request, const char *msgTypeName, StringBuffer &schema, BoolHash&added, const char *xns=\"xsd\", const char *wsns=\"tns\", unsigned flags=1);\n");
  2871. //method ==> getMapInfo
  2872. outs("\tstatic void getMapInfo(IMapInfo& info);\n");
  2873. outs("\tstatic void getMapInfo(IMapInfo& info, BoolHash& added);\n");
  2874. //method ==> getHtmlForm
  2875. outs("\tstatic StringBuffer &getHtmlForm(IEspContext &context, CHttpRequest* request, const char *serv, const char *method, StringBuffer &form, bool includeFormTag=true, const char *prefix=NULL);\n");
  2876. //method ==> hasCustomHttpContent
  2877. outs("\tstatic bool hasCustomHttpContent()\n");
  2878. outs("\t{\n");
  2879. if (contentVar)
  2880. outs("\t\treturn true;\n");
  2881. else
  2882. outs("\t\treturn false;\n");
  2883. outs("\t}\n");
  2884. //method ==> serializeHtml
  2885. outs("\tStringBuffer &serializeHtml(IEspContext &context, const char *serv, const char *method, StringBuffer &html);\n");
  2886. //method ==> serialize (IRpcMessage&)
  2887. outs("\n\tvoid serialize(IRpcMessage& rpc_resp);\n");
  2888. //method ==> copy
  2889. outf("\n\tvoid copy(C%s &from);\n", name_);
  2890. //method ==> copy from interface
  2891. outf("\n\tvoid copy(IConst%s &ifrom);\n", name_);
  2892. //method ==> serializeContent (StringBuffer&)
  2893. outs("\n\tvoid serializeContent(IEspContext* ctx, StringBuffer& buffer, IProperties **pprops=NULL);\n");
  2894. outs("\n\tvoid serializeAttributes(IEspContext* ctx, StringBuffer& s);\n");
  2895. outs("\n\tvoid getAttributes(IProperties &attributes);\n");
  2896. //method ==> serialize (StringBuffer&)
  2897. outf("\n\tstatic void serializer(IEspContext* ctx, IConst%s &ifrom, StringBuffer& buffer, bool keepRootTag=true);\n", name_);
  2898. //method ==> serialize (MemoryBuffer&, StringBuffer &)
  2899. if (contentVar)
  2900. outs("\n\tvoid appendContent(IEspContext* ctx, MemoryBuffer& buffer, StringBuffer &mimetype);\n");
  2901. outs("\tvoid setEventSink(void * val){m_eventSink=val;}\n");
  2902. outs("\tvoid * getEventSink(){return m_eventSink;}\n");
  2903. outs("\tvoid setState(IInterface * val){m_RequestState = val;}\n");
  2904. outs("\tIInterface * queryState(){return m_RequestState;}\n");
  2905. outs("\tvoid setMethod(const char * method){m_methodName.set(method);}\n");
  2906. outs("\tconst char * getMethod(){return m_methodName.str();}\n\n");
  2907. outs("\tvoid setReqId(unsigned val){soap_reqid=val;}\n");
  2908. outs("\tunsigned getReqId(){return soap_reqid;}\n\n");
  2909. outs("\tvoid lock(){m_mutex.lock();}\n");
  2910. outs("\tvoid unlock(){m_mutex.unlock();}\n\n");
  2911. if (getMetaInt("element")!=0)
  2912. {
  2913. outs(1, "void set_tag_value(const char * value){m_tag_value.set(value);}\n");
  2914. outs(1, "const char * get_tag_value(){return m_tag_value.str();}\n\n");
  2915. }
  2916. outs("\n\tbool unserialize(IRpcMessage& rpc_request, const char *tagname, const char *basepath);\n");
  2917. if (parent)
  2918. {
  2919. outs("\n\tbool localUnserialize(IRpcMessage& rpc_request, const char *tagname, const char *basepath);\n");
  2920. outs("\n\tbool unserialize(IEspContext* ctx, CSoapValue& soapval, bool localOnly=false);\n");
  2921. outs("\n\tbool unserialize(IEspContext* ctx, IProperties& params, MapStrToBuf *attachments, const char *basepath=NULL, bool localOnly=false);\n");
  2922. }
  2923. else
  2924. {
  2925. outs("\n\tbool unserialize(IEspContext* ctx, CSoapValue& soapval);\n");
  2926. outs("\n\tbool unserialize(IEspContext* ctx, IProperties& params, MapStrToBuf *attachments, const char *basepath=NULL);\n");
  2927. }
  2928. //outs("\n\tvoid unserialize(const char * msg);\n");
  2929. if (espm_type_==espm_response)
  2930. {
  2931. outs("\n\tvirtual void setRedirectUrl(const char *url)\n");
  2932. outs("\t{ CSoapResponseBinding::setRedirectUrl(url); }\n");
  2933. outs("\n\tvirtual const IMultiException& getExceptions()\n");
  2934. outs("\t{ return CSoapResponseBinding::getExceptions(); }\n");
  2935. outs("\n\tvirtual int queryClientStatus()\n");
  2936. outs("\t{ return CSoapResponseBinding::getRpcState(); }\n");
  2937. outs("\n\tvirtual void noteException(IException& e)\n");
  2938. outs("\t{ CSoapResponseBinding::noteException(e); }\n");
  2939. }
  2940. outs("\n");
  2941. write_esp_methods(espaxm_both, true, false);
  2942. outs("};\n\n");
  2943. }
  2944. bool EspMessageInfo::hasMapInfo()
  2945. {
  2946. for (ParamInfo* pi=getParams();pi!=NULL;pi=pi->next)
  2947. if (pi->hasMapInfo())
  2948. return true;
  2949. return false;
  2950. }
  2951. void EspMessageInfo::write_esp()
  2952. {
  2953. if (espm_type_ == espm_enum)
  2954. return;
  2955. const char *parent=getParentName();
  2956. ParamInfo *contentVar=NULL;
  2957. ParamInfo *pi=NULL;
  2958. bool removeNil=(getMetaInt("nil_remove", 0)!=0);
  2959. for (pi=getParams();pi!=NULL;pi=pi->next)
  2960. {
  2961. if (pi->getMetaString("http_content", NULL)!=NULL)
  2962. {
  2963. contentVar=pi;
  2964. break;
  2965. }
  2966. }
  2967. //comment
  2968. outs("\n//=======================================================");
  2969. outf("\n// class C%s Implementation", name_);
  2970. outs("\n//=======================================================");
  2971. outs("\n");
  2972. //default constructor
  2973. outf("\nC%s::C%s(const char *serviceName, IRpcMessageBinding *init)", name_, name_);
  2974. bool isFirstInited=true;
  2975. if (parent)
  2976. {
  2977. outf(" : C%s(serviceName, init)", parent);
  2978. isFirstInited=false;
  2979. }
  2980. for (pi=getParams();pi!=NULL;pi=pi->next)
  2981. {
  2982. pi->write_esp_init(isFirstInited, removeNil);
  2983. }
  2984. if (contentVar)
  2985. {
  2986. outs((isFirstInited) ? "\n\t: " : ",");
  2987. outf("m_%s_mimetype(%s)", contentVar->name, contentVar->getMetaString("http_content", "\"text/xml; charset=UTF-8\""));
  2988. }
  2989. outs("\n{\n");
  2990. outs("\tm_eventSink=NULL;\n");
  2991. outs("\tm_RequestState=NULL;\n");
  2992. outs("\tm_serviceName.append(serviceName);\n");
  2993. outf("\tm_msgName.append(\"%s\");\n", name_);
  2994. outs("\tif (init)\n");
  2995. outs("\t{\n");
  2996. outs("\t\tsetClientValue(init->getClientValue());\n");
  2997. outs("\t\tsetReqId(init->getReqId());\n");
  2998. outs("\t\tsetEventSink(init->getEventSink());\n");
  2999. outs("\t\tsetState(init->queryState());\n");
  3000. outs("\t\tsetThunkHandle(init->getThunkHandle());\n");
  3001. outs("\t\tsetMethod(init->getMethod());\n");
  3002. outs("\t}\n");
  3003. outs("}\n");
  3004. outf("\nC%s::C%s(const char *serviceName, const char *bc)", name_, name_);
  3005. isFirstInited=true;
  3006. if (parent)
  3007. {
  3008. outf(" : C%s(serviceName)", parent);
  3009. isFirstInited=false;
  3010. }
  3011. for (pi=getParams();pi!=NULL;pi=pi->next)
  3012. {
  3013. pi->write_esp_init(isFirstInited, removeNil);
  3014. }
  3015. if (contentVar)
  3016. {
  3017. outs((isFirstInited) ? " : " : ", ");
  3018. outf("m_%s_mimetype(%s)", contentVar->name, contentVar->getMetaString("http_content", "\"text/xml; charset=UTF-8\""));
  3019. }
  3020. outs("\n{\n");
  3021. outs("\tm_eventSink=NULL;\n");
  3022. outs("\tm_RequestState=NULL;\n");
  3023. outs("\tm_serviceName.append(serviceName);\n");
  3024. outf("\tm_msgName.append(\"%s\");\n", name_);
  3025. outs("}\n");
  3026. if (espm_type_==espm_struct)
  3027. {
  3028. //Raw message constructor
  3029. /*
  3030. outf("\nC%s::C%s(const char *serviceName, const char * msg)", name_, name_);
  3031. isFirstInited=true;
  3032. if (parent)
  3033. {
  3034. outf(" : C%s(serviceName, msg)", parent);
  3035. isFirstInited=false;
  3036. }
  3037. for (pi=getParams();pi!=NULL;pi=pi->next)
  3038. {
  3039. pi->write_esp_init(isFirstInited, removeNil);
  3040. }
  3041. if (contentVar)
  3042. {
  3043. outs((isFirstInited) ? " : " : ", ");
  3044. outf("m_%s_mimetype(%s)", contentVar->name, contentVar->getMetaString("http_content", "\"text/xml; charset=UTF-8\""));
  3045. }
  3046. outs("\n\t{\n\t\tm_eventSink=NULL;\n");
  3047. outs("\t\tm_RequestState=NULL;\n");
  3048. outs("\t\tm_serviceName.append(serviceName);\n");
  3049. outf("\t\tm_msgName.append(\"%s\");\n", name_);
  3050. outs("\t\tunserialize(msg);\n\t}\n");
  3051. */
  3052. }
  3053. else
  3054. {
  3055. //rpc message constructor
  3056. outf("\nC%s::C%s(const char *serviceName, IRpcMessage* rpcmsg)", name_, name_);
  3057. isFirstInited=true;
  3058. if (parent)
  3059. {
  3060. outf(" : C%s(serviceName, rpcmsg)", parent);
  3061. isFirstInited=false;
  3062. }
  3063. for (pi=getParams();pi!=NULL;pi=pi->next)
  3064. {
  3065. pi->write_esp_init(isFirstInited, removeNil);
  3066. }
  3067. if (contentVar)
  3068. {
  3069. outs((isFirstInited) ? " : " : ", ");
  3070. outf("m_%s_mimetype(%s)", contentVar->name, contentVar->getMetaString("http_content", "\"text/xml; charset=UTF-8\""));
  3071. }
  3072. outs("\n{\n");
  3073. outs("\tm_eventSink=NULL;\n");
  3074. outs("\tm_RequestState=NULL;\n");
  3075. outs("\tm_serviceName.append(serviceName);\n");
  3076. outf("\tm_msgName.append(\"%s\");\n", name_);
  3077. if (parent)
  3078. outs("\tlocalUnserialize(*rpcmsg,NULL,NULL);\n");
  3079. else
  3080. outs("\tunserialize(*rpcmsg,NULL,NULL);\n");
  3081. outs("}\n");
  3082. //IProperties constructor
  3083. outf("\nC%s::C%s(IEspContext* ctx, const char *serviceName, IProperties *params, MapStrToBuf *attachments)", name_, name_);
  3084. isFirstInited=true;
  3085. if (parent)
  3086. {
  3087. outf(" : C%s(ctx, serviceName, params, attachments)", parent);
  3088. isFirstInited=false;
  3089. }
  3090. for (pi=getParams();pi!=NULL;pi=pi->next)
  3091. {
  3092. pi->write_esp_init(isFirstInited, removeNil);
  3093. }
  3094. if (contentVar)
  3095. {
  3096. outs((isFirstInited) ? " : " : ", ");
  3097. outf("m_%s_mimetype(%s)", contentVar->name, contentVar->getMetaString("http_content", "\"text/xml; charset=UTF-8\""));
  3098. }
  3099. outs("\n{\n\tm_eventSink=NULL;\n");
  3100. outs("\tm_RequestState=NULL;\n");
  3101. outs("\tm_serviceName.append(serviceName);\n");
  3102. outf("\tm_msgName.append(\"%s\");\n", name_);
  3103. if (parent)
  3104. outs("\tunserialize(ctx,*params,attachments, NULL,true);\n}\n");
  3105. else
  3106. outs("\tunserialize(ctx,*params,attachments, NULL);\n}\n");
  3107. }
  3108. //=======================================================================================
  3109. //method ==> getXsdDefinition
  3110. // @context: the context could affect the schema, e.g., the version, the URL parameters
  3111. // @flags: 0x001 - define the struct/enum as complexType.
  3112. // 0x010 - do not include group-type enclosure (i.e., just define the fields, e.g., as part of other complex type definition)
  3113. // 0x100 - do not include fields at all (only to include definitions of fields, recursively)
  3114. bool isExtSimpleType = getMetaInt("element", 0)!=0;
  3115. outf("\nStringBuffer &C%s::getXsdDefinition(IEspContext &context, CHttpRequest* request, const char *msgTypeName, StringBuffer &schema, BoolHash &added, const char *xns, const char *wsns, unsigned flags)\n", name_);
  3116. outs("{\n");
  3117. indentReset(1);
  3118. indentOuts("if (!(flags & 0x100))\n\t{\n");
  3119. indentOuts(1,"IProperties *props = request->queryParameters();\n");
  3120. indentOuts("if(msgTypeName) {\n");
  3121. indentOuts(1,"if(added.getValue(msgTypeName))\n");
  3122. indentOuts1(1,"return schema;\n");
  3123. indentOuts("else\n");
  3124. indentOuts1(1,"added.setValue(msgTypeName, 1);\n");
  3125. indentOuts(-1,"}\n");
  3126. indentOuts("if (flags & 0x01) {\n");
  3127. bool isEmptyComplexType = true; //a complex type with no children, no attribute and no parent
  3128. if (isExtSimpleType || getParentName() || hasNonAttributeChild() || (espm_type_==espm_response && getMetaInt("exceptions_inline", 0)))
  3129. isEmptyComplexType = false;
  3130. else
  3131. {
  3132. for (pi=getParams();pi!=NULL;pi=pi->next)
  3133. {
  3134. if (!pi->getMetaInt("attribute", 0) && !pi->getMetaInt("hidden", 0) && !pi->getMetaInt("hidden_soap", 0))
  3135. isEmptyComplexType = false;
  3136. }
  3137. }
  3138. if (isEmptyComplexType)
  3139. {
  3140. if (espm_type_==espm_struct)
  3141. indentOuts(1,"schema.appendf(\"<xsd:complexType name=\\\"%s\\\"><xsd:all/></xsd:complexType>\\n\", msgTypeName);\n");
  3142. else
  3143. indentOuts(1,"schema.appendf(\"<xsd:element name=\\\"%s\\\"><xsd:complexType><xsd:all/></xsd:complexType></xsd:element>\\n\", msgTypeName);\n");
  3144. }
  3145. else if (espm_type_==espm_struct)
  3146. indentOuts(1,"schema.appendf(\"<xsd:complexType name=\\\"%s\\\">\\n\", msgTypeName);\n");
  3147. else
  3148. indentOuts(1,"schema.appendf(\"<xsd:element name=\\\"%s\\\"><xsd:complexType>\\n\", msgTypeName);\n");
  3149. if (isExtSimpleType)
  3150. indentOuts("schema.append(\"<xsd:simpleContent><xsd:extension base=\\\"xsd:string\\\">\\n\");\n");
  3151. indentOuts(-1, "}\n");
  3152. // native arrays
  3153. typedef std::map<std::string,std::string> EspNativeArrays;
  3154. EspNativeArrays nativeArrays;
  3155. // esp struct arrays
  3156. typedef std::set<std::string> EspStructArrays;
  3157. EspStructArrays structArrays;
  3158. //no element children for extended simple type
  3159. if (!isEmptyComplexType && !isExtSimpleType)
  3160. {
  3161. const char *xsdGroupType = getXsdGroupType();
  3162. bool hasChild = hasNonAttributeChild();
  3163. bool exceptions = espm_type_==espm_response && getMetaInt("exceptions_inline", 0);
  3164. bool needGroupType = exceptions || hasChild || parent;
  3165. if (needGroupType)
  3166. {
  3167. indentOuts("if (!(flags & 0x10)) {\n");
  3168. indentOutf1(1,"schema.append(\"<xsd:%s>\");\n", xsdGroupType);
  3169. if (exceptions)
  3170. indentOuts("schema.append(\"<xsd:element name=\\\"Exceptions\\\" type=\\\"tns:ArrayOfEspException\\\" minOccurs=\\\"0\\\" maxOccurs=\\\"1\\\"/>\");\n");
  3171. indentOuts("}\n");
  3172. }
  3173. if (parent)
  3174. indentOutf("C%s::getXsdDefinition(context, request, NULL, schema, added, xns, wsns, 0x10);\n", parent);
  3175. for (pi=getParams();pi!=NULL;pi=pi->next)
  3176. {
  3177. if (!pi->getMetaInt("attribute", 0) && !pi->getMetaInt("hidden", 0) && !pi->getMetaInt("hidden_soap", 0))
  3178. {
  3179. enum {definedtype, inline_primitive_array, inline_array, complextype} complexity=definedtype;
  3180. StrBuffer buffer;
  3181. const char *xsd_type = pi->getMetaXsdType();
  3182. if (xsd_type)
  3183. {
  3184. buffer.append(xsd_type);
  3185. }
  3186. else if (pi->flags & PF_TEMPLATE)
  3187. {
  3188. if (!strcmp(pi->templ, "ESParray"))
  3189. {
  3190. if (pi->isPrimitiveArray())
  3191. {
  3192. if (pi->getMetaString("item_tag", NULL))
  3193. complexity=inline_primitive_array;
  3194. else {
  3195. const char* type = pi->getArrayImplType();
  3196. nativeArrays[pi->getArrayItemXsdType()] = VStrBuffer("Esp%s", type).str();
  3197. buffer.appendf("tns:Esp%s", type);
  3198. }
  3199. }
  3200. else
  3201. {
  3202. buffer.append("tns:");
  3203. if (pi->getMetaString("item_tag", NULL))
  3204. complexity=inline_array;
  3205. else {
  3206. structArrays.insert(pi->typname);
  3207. buffer.append("ArrayOf");
  3208. }
  3209. buffer.append(pi->typname);
  3210. }
  3211. }
  3212. else
  3213. buffer.append("xsd:string");
  3214. }
  3215. else if (pi->kind==TK_ESPSTRUCT || pi->kind==TK_ESPENUM)
  3216. {
  3217. buffer.appendf("tns:%s",pi->typname);
  3218. }
  3219. else
  3220. {
  3221. buffer.append(pi->getXsdType());
  3222. }
  3223. const char *xsdtype = buffer.str();
  3224. const char *xsdns = "";
  3225. if (xsdtype)
  3226. {
  3227. int count= buffer.length();
  3228. if (count>0 && buffer.charAt(count-1)=='\"')
  3229. buffer.setCharAt(count-1,0);
  3230. if (*xsdtype=='\"')
  3231. xsdtype++;
  3232. if (strchr(xsdtype, ':')==NULL)
  3233. xsdns="xsd:";
  3234. }
  3235. bool hasMapInfo = pi->hasMapInfo();
  3236. if (hasMapInfo)
  3237. {
  3238. indentOutf("if (!context.suppressed(\"%s\",\"%s\")) {\n", this->name_, pi->name);
  3239. indentInc(1);
  3240. }
  3241. const char *access=pi->getMetaString("access", NULL);
  3242. if (access)
  3243. {
  3244. indentOuts("SecAccessFlags acc;\n");
  3245. indentOutf("if (context.authorizeFeature(%s, acc) && acc>=SecAccess_Read) {\n", access);
  3246. indentInc(1);
  3247. }
  3248. StrBuffer xmlTag;
  3249. const char* tagName = pi->getMetaStringValue(xmlTag,"xml_tag") ? xmlTag.str() : pi->name;
  3250. switch (complexity)
  3251. {
  3252. case inline_array:
  3253. {
  3254. indentOutf("schema.append(\"<xsd:element minOccurs=\\\"0\\\" name=\\\"%s\\\">\\n\");\n", tagName);
  3255. indentOuts("schema.append(\"<xsd:complexType><xsd:sequence>\\n\");\n");
  3256. indentOutf("schema.append(\"<xsd:element minOccurs=\\\"0\\\" maxOccurs=\\\"unbounded\\\" name=\\\"%s\\\" type=\\\"%s\\\"/>\");\n", pi->getMetaString("item_tag", "Item"), xsdtype);
  3257. indentOuts("schema.append(\"</xsd:sequence></xsd:complexType>\");\n");
  3258. indentOutf("schema.append(\"</xsd:element>\");\n");
  3259. break;
  3260. }
  3261. case inline_primitive_array:
  3262. {
  3263. indentOutf("schema.append(\"<xsd:element minOccurs=\\\"0\\\" name=\\\"%s\\\">\");\n", tagName);
  3264. indentOuts("schema.append(\"<xsd:complexType><xsd:sequence>\");\n");
  3265. indentOutf("schema.append(\"<xsd:element name=\\\"%s\\\" type=\\\"xsd:%s\\\" minOccurs=\\\"0\\\" maxOccurs=\\\"unbounded\\\"", pi->getMetaString("item_tag", "Item"), pi->getArrayItemXsdType());
  3266. int cols = pi->getMetaInt("cols",0);
  3267. int rows = pi->getMetaInt("rows",0);
  3268. if (cols>0 || rows>0)
  3269. {
  3270. outs("\");\n");
  3271. indentOuts("if (context.queryOptions()&ESPCTX_ALL_ANNOTATION)\n");
  3272. indentOuts(1,"schema.append(\"> <xsd:annotation><xsd:appinfo><form");
  3273. if (cols>0)
  3274. outf(" formCols=\\\"%d\\\"", cols);
  3275. if (rows>0)
  3276. outf(" formRows=\\\"%d\\\"", rows);
  3277. outs("/></xsd:appinfo></xsd:annotation></xsd:element>\\n\");\n");
  3278. indentOuts(-1,"else\n");
  3279. indentOuts("\tschema.append(\"/>\\n\");\n");
  3280. }
  3281. else
  3282. outs("/>\\n\");\n");
  3283. indentOuts("schema.append(\"</xsd:sequence></xsd:complexType>\\n\");\n");
  3284. indentOutf("schema.append(\"</xsd:element>\\n\");\n");
  3285. break;
  3286. }
  3287. case definedtype:
  3288. {
  3289. indentOutf("schema.append(\"<xsd:element");
  3290. // min occurs
  3291. int minOccurs = (pi->getMetaInt("required", 0)) ? 1 : 0;
  3292. if (minOccurs==0)
  3293. outs(" minOccurs=\\\"0\\\"");
  3294. // default value
  3295. if (pi->hasMetaTag("default"))
  3296. {
  3297. if (pi->kind==TK_CHAR || pi->kind==TK_UNSIGNEDCHAR || strcmp(xsdtype,"string")==0)
  3298. {
  3299. const char* val = pi->getMetaString("default",NULL);
  3300. if (val && *val)
  3301. {
  3302. // remove quotes
  3303. if (*val=='"' || *val=='\'')
  3304. {
  3305. char* s = strdup(val);
  3306. *(s+strlen(s)-1) = 0;
  3307. outf(" default=\\\"%s\\\"", s+1);
  3308. free(s);
  3309. }
  3310. else
  3311. outf(" default=\\\"%s\\\"", val);
  3312. }
  3313. }
  3314. else if (pi->kind==TK_DOUBLE || pi->kind==TK_FLOAT || strcmp(xsdtype,"double")==0)
  3315. {
  3316. double val = pi->getMetaDouble("default");
  3317. if (val==0)
  3318. val = pi->getMetaInt("default"); // auto conversion
  3319. if (val!=0)
  3320. outf(" default=\\\"%g\\\"", val);
  3321. }
  3322. else if (pi->kind==TK_BOOL || strcmp(xsdtype,"bool")==0)
  3323. {
  3324. outf(" default=\\\"%s\\\"", pi->getMetaInt("default") ? "true" : "false");
  3325. }
  3326. else if (pi->kind==TK_ESPENUM)
  3327. {
  3328. const char* val = pi->getMetaString("default",NULL);
  3329. if (val && *val)
  3330. {
  3331. // remove quotes
  3332. if (*val=='"' || *val=='\'')
  3333. {
  3334. char* s = strdup(val);
  3335. *(s+strlen(s)-1) = 0;
  3336. outf(" default=\\\"%s\\\"", s+1);
  3337. free(s);
  3338. }
  3339. else
  3340. outf(" default=\\\"%s\\\"", val);
  3341. }
  3342. else
  3343. {
  3344. int val = pi->getMetaInt("default", -1);
  3345. if (val != -1)
  3346. outf(" default=\\\"%d\\\"", val);
  3347. }
  3348. }
  3349. else// assume it is integer
  3350. {
  3351. int val = pi->getMetaInt("default");
  3352. if (val)
  3353. outf(" default=\\\"%d\\\"", val);
  3354. }
  3355. }
  3356. // name & type
  3357. outf(" name=\\\"%s\\\" type=\\\"%s%s\\\"", tagName, xsdns, xsdtype);
  3358. // check for annotations
  3359. StrBuffer annot;
  3360. const char* formType = pi->getMetaInt("password") ? "password" : NULL;
  3361. if (formType)
  3362. annot.appendf(" formType=\\\"%s\\\"",formType);
  3363. bool collapsed = pi->getMetaInt("collapsed")?true:false;;
  3364. if (collapsed)
  3365. annot.append(" collapsed=\\\"true\\\"");
  3366. int cols = pi->getMetaInt("cols",0);
  3367. if (cols>0)
  3368. annot.appendf(" formCols=\\\"%d\\\"", cols);
  3369. int rows = pi->getMetaInt("rows",0);
  3370. if (rows>0)
  3371. annot.appendf(" formRows=\\\"%d\\\"", rows);
  3372. StrBuffer tmp;
  3373. pi->getMetaStringValue(tmp,"form_ui");
  3374. if (tmp.length()) {
  3375. StrBuffer encoded;
  3376. encodeXML(tmp.str(),encoded);
  3377. annot.appendf(" ui=\\\"%s\\\"", printfEncode(encoded.str(), tmp.clear()).str());
  3378. }
  3379. pi->getMetaStringValue(tmp.clear(), "html_head");
  3380. if (tmp.length()) {
  3381. StrBuffer encoded;
  3382. encodeXML(tmp.str(),encoded);
  3383. annot.appendf(" html_head=\\\"%s\\\"", printfEncode(encoded.str(), tmp.clear()).str());
  3384. }
  3385. if (annot.length())
  3386. {
  3387. outs("\");\n");
  3388. indentOuts("if (context.queryOptions()&ESPCTX_ALL_ANNOTATION)\n");
  3389. indentOuts(1,"schema.append(\"> <xsd:annotation><xsd:appinfo><form");
  3390. outf("%s", annot.str());
  3391. outs("/></xsd:appinfo></xsd:annotation></xsd:element>\\n\");\n");
  3392. indentOuts(-1,"else\n");
  3393. indentOuts("\tschema.append(\"/>\\n\");\n");
  3394. }
  3395. else
  3396. outs("/>\\n\");\n");
  3397. break;
  3398. }
  3399. default:
  3400. break;
  3401. }
  3402. if (access)
  3403. indentOuts(-1,"}\n");
  3404. //if (optional)
  3405. if (hasMapInfo)
  3406. indentOuts(-1,"}\n");
  3407. }
  3408. }
  3409. if (needGroupType)
  3410. {
  3411. indentOuts("if (!(flags & 0x10))\n");
  3412. indentOutf1(1,"schema.append(\"</xsd:%s>\\n\");\n", xsdGroupType);
  3413. }
  3414. } //!isEmptyComplexType && !isExtSimpleType
  3415. if (!isEmptyComplexType)
  3416. {
  3417. //attributes last
  3418. for (pi=getParams();pi!=NULL;pi=pi->next)
  3419. {
  3420. if (pi->getMetaInt("attribute")!=0 && !pi->getMetaInt("hidden"))
  3421. {
  3422. StrBuffer tmp;
  3423. const char* tagName = pi->getMetaStringValue(tmp,"xml_tag") ? tmp.str() : pi->name;
  3424. indentOutf("schema.append(\"<xsd:attribute name=\\\"%s\\\" type=\\\"xsd:%s\\\"/>\");\n", tagName, pi->getXsdType());
  3425. }
  3426. }
  3427. indentOuts("if (flags & 0x01) {\n");
  3428. if (isExtSimpleType)
  3429. indentOuts1(1,"schema.append(\"</xsd:extension></xsd:simpleContent>\\n\");\n");
  3430. if (espm_type_==espm_struct)
  3431. indentOuts1(1,"schema.append(\"</xsd:complexType>\\n\");\n");
  3432. else
  3433. indentOuts1(1,"schema.append(\"</xsd:complexType></xsd:element>\\n\");\n");
  3434. indentOuts("}\n");
  3435. }
  3436. indentOuts(-1,"}\n"); // if (flags & 0x100)
  3437. //-------------------------------------------------------------------------
  3438. // try to figure out structs without ESPuses
  3439. // true if it is with map info, once a STRUCT or ENUM is there without map info, it is false
  3440. const int MIT_HasMap = 0x01;
  3441. const int MIT_IsEnum = 0x02;
  3442. const int MIT_IsStruct = 0x04;
  3443. enum MapInfoType { MIT_EnumFalse=MIT_IsEnum, MIT_EnumTrue=MIT_HasMap|MIT_IsEnum,
  3444. MIT_StructFalse=MIT_IsStruct,MIT_StructTrue=MIT_IsStruct|MIT_HasMap };
  3445. typedef std::map<std::string, int> TypeMap;
  3446. TypeMap typesNeeded;
  3447. bool parenthesisOpened = false;
  3448. if (parent)
  3449. {
  3450. outs("\tif (!(flags & 0x10) || (flags & 0x100))\n");
  3451. outs("\t{\n");
  3452. parenthesisOpened = true;
  3453. outf("\t\tC%s::getXsdDefinition(context, request, schema, added, xns, wsns, 0x110);\n", parent);
  3454. typesNeeded[parent] = false;
  3455. }
  3456. for (pi=getParams();pi!=NULL;pi=pi->next)
  3457. {
  3458. // we still need to make it usable for the service writer
  3459. //if (pi->getMetaInt("hidden", 0) || pi->getMetaInt("hidden_soap", 0))
  3460. // continue;
  3461. std::string thisType;
  3462. const char *xsd_type=pi->getMetaXsdType();
  3463. if (xsd_type)
  3464. {
  3465. char* buf = strdup(xsd_type[0]=='"' ? xsd_type+1 : xsd_type);
  3466. size_t count= strlen(buf);
  3467. if (count>0 && buf[count-1]=='\"')
  3468. buf[count-1]=0;
  3469. char* typeName = getToBeDefinedType(buf);
  3470. if (typeName)
  3471. {
  3472. thisType = typeName;
  3473. free(typeName);
  3474. }
  3475. free(buf);
  3476. }
  3477. else if (pi->kind==TK_ESPSTRUCT || pi->kind==TK_ESPENUM)
  3478. {
  3479. if (pi->typname)
  3480. thisType = pi->typname;
  3481. else
  3482. outs("\t\t*** pi->typname is empty!!\n");
  3483. }
  3484. else if (pi->flags & PF_TEMPLATE)
  3485. {
  3486. if (strcmp(pi->templ, "ESParray")==0)
  3487. {
  3488. if (pi->typname && strcmp(pi->typname, "string")!=0 && strcmp(pi->typname, "EspTextFile")!=0)
  3489. thisType = pi->typname;
  3490. }
  3491. else
  3492. outf("\t\t// *** skip field: name=%s, type=%s\n", pi->name, pi->typname);
  3493. }
  3494. if (thisType.length() && strcmp(thisType.c_str(),name_)!=0)
  3495. {
  3496. TypeMap::const_iterator it = typesNeeded.find(thisType);
  3497. if (it==typesNeeded.end() || (*it).second & MIT_HasMap) // thisType is not in typesNeeded or it is there with version info
  3498. {
  3499. if (!parenthesisOpened)
  3500. {
  3501. outs("\tif (!(flags & 0x10) || (flags & 0x100))\n\t{\n");
  3502. parenthesisOpened = true;
  3503. }
  3504. if (pi->hasMapInfo())
  3505. {
  3506. outf("\t\tif (!context.suppressed(\"%s\",\"%s\"))\n\t", this->name_, pi->name);
  3507. typesNeeded[thisType] = (pi->kind==TK_ESPENUM) ? MIT_EnumTrue : MIT_StructTrue;
  3508. }
  3509. else
  3510. typesNeeded[thisType] = (pi->kind==TK_ESPENUM) ? MIT_EnumFalse : MIT_StructFalse;
  3511. if (pi->kind == TK_ESPENUM)
  3512. outf("\t\tCX%s::getXsdDefinition(context, request, schema, added);\n", thisType.c_str());
  3513. else
  3514. outf("\t\tC%s::getXsdDefinition(context, request, schema, added);\n", thisType.c_str());
  3515. }
  3516. }
  3517. }
  3518. if (parenthesisOpened)
  3519. outs("\t}\n");
  3520. // native arrays
  3521. for (EspNativeArrays::const_iterator it = nativeArrays.begin(); it!=nativeArrays.end(); it++)
  3522. {
  3523. outf("\tif (added.getValue(\"%s\")==NULL) {\n", (*it).second.c_str());
  3524. outf("\t\taddEspNativeArray(schema,\"%s\",\"%s\");\n", (*it).first.c_str(), (*it).second.c_str());
  3525. outf("\t\tadded.setValue(\"%s\",1);\n", (*it).second.c_str());
  3526. outf("\t}\n");
  3527. }
  3528. // struct arrays
  3529. for (EspStructArrays::const_iterator it2 = structArrays.begin(); it2!=structArrays.end(); it2++)
  3530. {
  3531. const char* type = (*it2).c_str();
  3532. outf("\tif (added.getValue(\"%s\") && added.getValue(\"ArrayOf%s\")==NULL) {\n", type, type);
  3533. outf("\t\tschema.append(\"<xsd:complexType name=\\\"ArrayOf%s\\\">\\n\");\n",type);
  3534. outf("\t\tschema.append(\"<xsd:sequence>\\n\");\n");
  3535. outf("\t\tschema.append(\"<xsd:element minOccurs=\\\"0\\\" maxOccurs=\\\"unbounded\\\" name=\\\"%s\\\" type=\\\"tns:%s\\\"/>\\n\");\n", type, type);
  3536. outf("\t\tschema.append(\"</xsd:sequence>\\n\");\n");
  3537. outf("\t\tschema.append(\"</xsd:complexType>\\n\");\n");
  3538. outf("\t\tadded.setValue(\"ArrayOf%s\",1);\n", type);
  3539. outf("\t}\n");
  3540. }
  3541. /*
  3542. //typesNeeded.erase(name_); // Do not include self: avoid recursive call
  3543. if (typesNeeded.size()>0)
  3544. {
  3545. outs("\tif (!(flags & 0x10))\n");
  3546. outs("\t{\n");
  3547. for (TypeMap::const_iterator it = typesNeeded.begin(); it!=typesNeeded.end(); ++it)
  3548. {
  3549. const char* type = (*it).first.c_str();
  3550. const char* fld = (*it).second.c_str();
  3551. if (fld[0] != 0)
  3552. {
  3553. outf("\t\tif (!context.suppressed(\"%s\",\"%s\"))\n\t", this->name_, fld);
  3554. outf("\t\t\tC%s::getXsdDefinition(context, request, schema, added);\n", type);
  3555. }
  3556. else
  3557. outf("\t\tC%s::getXsdDefinition(context, request, schema, added);\n", type);
  3558. }
  3559. outs("\t}\n");
  3560. }
  3561. */
  3562. outs("\treturn schema;\n");
  3563. outs("}\n");
  3564. //=======================================================================================
  3565. //method ==> getMapInfo
  3566. outf("\nvoid C%s::getMapInfo(IMapInfo& info) { BoolHash added; getMapInfo(info, added); }\n",name_);
  3567. outf("\nvoid C%s::getMapInfo(IMapInfo& info, BoolHash& added)\n",name_);
  3568. outf("{\n");
  3569. for (pi=getParams();pi!=NULL;pi=pi->next)
  3570. {
  3571. if (pi->hasMapInfo())
  3572. {
  3573. StrBuffer ver;
  3574. bool hasVer = pi->getMetaVerInfo("min_ver",ver);
  3575. if (hasVer)
  3576. outf("\tinfo.addMinVersion(\"%s\",\"%s\",%s);\n", name_, pi->name, ver.str());
  3577. hasVer = pi->getMetaVerInfo("depr_ver",ver.clear());
  3578. if (hasVer)
  3579. outf("\tinfo.addDeprVersion(\"%s\",\"%s\",%s);\n", name_, pi->name, ver.str());
  3580. hasVer = pi->getMetaVerInfo("max_ver",ver.clear());
  3581. if (hasVer)
  3582. outf("\tinfo.addMaxVersion(\"%s\",\"%s\",%s);\n", name_, pi->name, ver.str());
  3583. const char* opt = pi->getMetaString("optional", NULL);
  3584. if (opt)
  3585. {
  3586. const char* quote = (*opt=='"' || *opt=='\'') ? "" : "\"";
  3587. outf("\tinfo.addOptional(\"%s\",\"%s\",%s%s%s);\n", name_, pi->name,quote,opt,quote);
  3588. }
  3589. }
  3590. }
  3591. if (typesNeeded.size()>0)
  3592. {
  3593. for (TypeMap::const_iterator it = typesNeeded.begin(); it!=typesNeeded.end(); ++it)
  3594. {
  3595. outf("\tif (!added.getValue(\"%s\"))\n", (*it).first.c_str());
  3596. outf("\t{\n");
  3597. outf("\t\tadded.setValue(\"%s\",1);\n", (*it).first.c_str());
  3598. outf("\t\tC%s%s::getMapInfo(info,added);\n",((*it).second & MIT_IsEnum)?"X":"",(*it).first.c_str());
  3599. outf("\t}\n");
  3600. }
  3601. }
  3602. outs("}\n");
  3603. //=======================================================================================
  3604. //method ==> getHtmlForm
  3605. //TODO: move includeFormTag into onGetForm() to reduce significant generated code
  3606. indentReset();
  3607. indentOutf("\nStringBuffer &C%s::getHtmlForm(IEspContext &context, CHttpRequest* request, const char *serv, const char *method, StringBuffer &form, bool includeFormTag, const char *prefix)\n", name_);
  3608. indentOuts("{\n");
  3609. indentOuts(1,"IProperties *props = request->queryParameters();\n");
  3610. bool hasAttachment=false;
  3611. for (pi=getParams();pi;pi=pi->next)
  3612. {
  3613. if (pi->typname && !stricmp("EspTextFile", pi->typname))
  3614. hasAttachment=true;
  3615. }
  3616. indentOuts("if (includeFormTag) {\n");
  3617. indentOutf(1,"StringBuffer params, versionTag;\n");
  3618. indentOuts("bool hasVersion = getUrlParams(props,params);\n");
  3619. indentOuts("if (!hasVersion) versionTag.appendf(\"%cver_=%g\",params.length()?'&':'?',context.getClientVersion());\n");
  3620. indentOutf("form.appendf(\"\\n<form name=\\\"esp_form\\\" method=\\\"POST\\\" enctype=\\\"%s\\\" action=\\\"/%%s/%%s%%s%%s\\\">\\n\", serv, method, params.str(), versionTag.str());\n",
  3621. hasAttachment ? "multipart/form-data" : "application/x-www-form-urlencoded");
  3622. indentOutf(-1,"}\n");
  3623. if (parent)
  3624. indentOutf("C%s::getHtmlForm(context, request, serv, method, form, false, prefix);\n", parent);
  3625. indentOuts("StringBuffer extfix;\n");
  3626. indentOuts("form.append(\" <table>\\n\");\n");
  3627. for (pi=getParams();pi!=NULL;pi=pi->next)
  3628. {
  3629. bool hasMapInfo = pi->hasMapInfo();
  3630. if (hasMapInfo)
  3631. {
  3632. indentOutf("if (!context.suppressed(\"%s\",\"%s\")) {\n", this->name_, pi->name);
  3633. indentInc(1);
  3634. }
  3635. if (!pi->getMetaInt("hidden"))
  3636. {
  3637. int rows = pi->getMetaInt("rows", 5);
  3638. StrBuffer label;
  3639. if (!pi->getMetaStringValue(label,"label"))
  3640. if (!pi->getMetaStringValue(label,"xml_tag"))
  3641. label = pi->name;
  3642. if (pi->getMetaInt("rows") || (pi->flags & PF_TEMPLATE))
  3643. {
  3644. int cols = pi->getMetaInt("cols", 50);
  3645. indentOuts("extfix.clear();\n");
  3646. indentOuts("if (prefix && *prefix)\n");
  3647. indentOuts1(1,"extfix.append(prefix).append(\".\");\n");
  3648. indentOutf("extfix.append(\"%s\");\n", pi->name);
  3649. indentOutf("form.appendf(\"<tr><td><b>%s: </b></td><td>\");\n", label.str());
  3650. if (!pi->isEspStringArray())
  3651. {
  3652. // handle default value
  3653. StrBuffer tmp;
  3654. const char* def = pi->getMetaStringValue(tmp,"default") ? tmp.str() : "";
  3655. indentOutf("form.appendf(\"<table><tr><td><textarea name=\\\"%%s\\\" cols=\\\"%d\\\" rows=\\\"%d\\\">%s</textarea></td>\", extfix.str());\n",
  3656. cols, rows, def);
  3657. indentOutf("form.append(\"</tr></table>\");\n");
  3658. }
  3659. else
  3660. {
  3661. indentOutf("form.appendf(\"<textarea name=\\\"%%s\\\" cols=\\\"%d\\\" rows=\\\"%d\\\"></textarea>\", extfix.str());\n", cols, rows);
  3662. }
  3663. indentOutf("form.append(\"</td></tr>\");\n");
  3664. }
  3665. else
  3666. {
  3667. esp_xlate_info *espinfo = esp_xlat(pi);
  3668. if (pi->kind==TK_ESPSTRUCT)
  3669. {
  3670. indentOuts("extfix.clear();\n");
  3671. indentOuts("if (prefix && *prefix)\n");
  3672. indentOuts1(1,"extfix.append(prefix).append(\".\");\n");
  3673. indentOutf("extfix.append(\"%s\");\n", pi->getXmlTag());
  3674. indentOutf("form.append(\"<tr>\").append(\"<td><b>%s: </b></td><td><hr/>\");\n", label.str());
  3675. indentOutf("C%s::getHtmlForm(context, request, serv, method, form, false, extfix.str());\n", pi->typname);
  3676. indentOuts("form.append(\"<hr/></td></tr>\");\n");
  3677. }
  3678. else if (espinfo->access_kind==TK_BOOL)
  3679. {
  3680. indentOuts("extfix.clear();\n");
  3681. indentOuts("if (prefix && *prefix)\n");
  3682. indentOuts1(1,"extfix.append(prefix).append(\".\");\n");
  3683. indentOutf("extfix.append(\"%s\");\n", pi->getXmlTag());
  3684. // handle default value
  3685. indentOutf("\n\tform.appendf(\" <tr><td><b>%s? </b></td><td><input type=\\\"checkbox\\\" name=\\\"%%s\\\" value=\\\"1\\\" %s /></td></tr>\\n\", extfix.str());\n",
  3686. label.str(), pi->getMetaInt("default",0)?"checked=\\\"1\\\"":"");
  3687. }
  3688. else if (espinfo->access_kind==TK_INT || espinfo->access_kind==TK_UNSIGNED
  3689. || espinfo->access_kind==TK_SHORT || espinfo->access_kind==TK_UNSIGNEDSHORT)
  3690. {
  3691. indentOuts("extfix.clear();\n");
  3692. indentOuts("if (prefix && *prefix) extfix.append(prefix).append(\".\");\n");
  3693. indentOutf("\textfix.append(\"%s\");\n", pi->getXmlTag());
  3694. int cols = pi->getMetaInt("cols", 20);
  3695. indentOutf("form.appendf(\" <tr><td><b>%s: </b></td><td><input type=\\\"text\\\" name=\\\"%%s\\\" size=\\\"%d\\\"", label.str(), cols);
  3696. int defValue = pi->getMetaInt("default");
  3697. if (defValue!=0)
  3698. indentOutf(" value=\\\"%d\\\"", defValue);
  3699. outs("/>\", extfix.str());\n");
  3700. indentOuts("form.append(\"</td></tr>\\n\");\n");
  3701. }
  3702. //TODO: handle default value for float, double, long, longlong etc
  3703. else
  3704. {
  3705. const char *xsdtype = pi->getXsdType();
  3706. bool isDate = (!stricmp(xsdtype, "date"));
  3707. const char *inputType = "text";
  3708. if (pi->typname && !strcmp(pi->typname, "EspTextFile"))
  3709. inputType="file";
  3710. else if (pi->getMetaInt("password"))
  3711. inputType="password";
  3712. indentOuts("extfix.clear();\n");
  3713. indentOuts("if (prefix && *prefix)\n");
  3714. indentOuts1(1,"extfix.append(prefix).append(\".\");\n");
  3715. indentOutf("extfix.append(\"%s\");\n", pi->getXmlTag());
  3716. // handle default value
  3717. StrBuffer tmp;
  3718. const char* def = pi->getMetaStringValue(tmp,"default") ? tmp.str() : "";
  3719. int cols = pi->getMetaInt("cols", isDate ? 20 : 50);
  3720. indentOutf("form.appendf(\" <tr><td><b>%s: </b></td><td><input type=\\\"%s\\\" name=\\\"%%s\\\" size=\\\"%d\\\" value=\\\"%s\\\" />\", extfix.str());\n", label.str(), inputType, cols, def);
  3721. if (isDate)
  3722. indentOutf("form.append(\"<a href=\\\"javascript:show_calendar('%s');\\\"><img src=\\\"files_/img/cal.gif\\\" width=\\\"16\\\" height=\\\"16\\\" border=\\\"0\\\" alt=\\\"Pick Date\\\"/><br/>\");\n", pi->name);
  3723. indentOuts("form.append(\"</td></tr>\\n\");\n");
  3724. }
  3725. }
  3726. }
  3727. if (hasMapInfo)
  3728. indentOuts(-1,"}\n");
  3729. }
  3730. indentReset(1);
  3731. indentOuts("if (includeFormTag) {\n");
  3732. indentOuts(1,"form.append(\"<tr><td></td><td><input type=\\\"submit\\\" value=\\\"Submit\\\" name=\\\"S1\\\" />\");\n");
  3733. indentOuts("form.append(\" &nbsp; <input type=\\\"reset\\\" value=\\\"Clear\\\"/> </td> </tr>\");\n");
  3734. indentOuts(-1,"}\n");
  3735. indentOuts("form.append(\"</table>\");\n");
  3736. indentOuts("if (includeFormTag)\n");
  3737. indentOuts(1,"form.append(\"</form>\");\n");
  3738. indentOuts(-1,"return form;\n");
  3739. indentOuts(-1,"}\n");
  3740. //method ==> serializeHtml
  3741. outf("\nStringBuffer &C%s::serializeHtml(IEspContext &context, const char *serv, const char *method, StringBuffer &html)\n", name_);
  3742. outs("{\n");
  3743. if (getMetaInt("serialize_html"))
  3744. {
  3745. outs("\thtml.append(\"<p align=\\\"left\\\">\");\n");
  3746. if (contentVar)
  3747. {
  3748. if (!(contentVar->flags & PF_TEMPLATE))
  3749. {
  3750. if (contentVar->typname!=NULL && strcmp(contentVar->typname, "EspResultSet")==0)
  3751. {
  3752. outf("\thtml.appendf(\"<br/><b>%s: </b><br/>\");\n", contentVar->name);
  3753. outf("\tEspHttpBinding::formatHtmlResultSet(context, serv, method, m_%s->str(), html);", contentVar->name);
  3754. }
  3755. else if (contentVar->typname==NULL || strcmp(contentVar->typname, "binary")!=0)
  3756. {
  3757. outf("\thtml.appendf(\"<br/><b>%s: </b><br/><input type=\\\"text\\\" name=\\\"%s\\\" size=\\\"50\\\" readonly=\\\"1\\\" value=\\\"\").append(m_%s.getValue()).append(\"\\\"/>\");\n", contentVar->name, contentVar->name, contentVar->name);
  3758. }
  3759. }
  3760. }
  3761. else
  3762. {
  3763. for (pi=getParams();pi!=NULL;pi=pi->next)
  3764. {
  3765. if (!(pi->flags & PF_TEMPLATE) && (pi->kind!=TK_ESPSTRUCT))
  3766. {
  3767. if (pi->typname!=NULL && strcmp(pi->typname, "EspResultSet")==0)
  3768. {
  3769. outf("\thtml.appendf(\"<br/><b>%s: </b><br/>\");\n", pi->name);
  3770. outf("\tEspHttpBinding::formatHtmlResultSet(context, serv, method, m_%s->str(), html);", pi->name);
  3771. }
  3772. else if (pi->typname==NULL || strcmp(pi->typname, "binary")!=0)
  3773. {
  3774. outf("\thtml.appendf(\"<br/><b>%s: </b><br/><input type=\\\"text\\\" name=\\\"%s\\\" size=\\\"50\\\" readonly=\\\"1\\\" value=\\\"\").append(m_%s.getValue()).append(\"\\\"/>\");\n", pi->name, pi->name, pi->name);
  3775. }
  3776. }
  3777. }
  3778. }
  3779. outs("\thtml.append(\"</p>\");\n");
  3780. }
  3781. outs("\treturn html;\n");
  3782. outs("}\n");
  3783. //method ==> serialize (IRpcMessage&)
  3784. outf("\nvoid C%s::serialize(IRpcMessage& rpc_resp)\n{\n", name_);
  3785. if (parent)
  3786. outf("\tC%s::serialize(rpc_resp);\n", parent);
  3787. // versioning
  3788. if (hasMapInfo())
  3789. {
  3790. outf("\tIEspContext* ctx = rpc_resp.queryContext();\n");
  3791. outf("\tdouble clientVer= ctx ? ctx->getClientVersion() : -1; /* no context gets everything */\n");
  3792. }
  3793. outf("\trpc_resp.set_ns(%s);\n", getMetaString("ns_var", "\"\""));
  3794. outs("\trpc_resp.set_name(m_msgName.str());\n");
  3795. const char *nsuri = getMetaString("ns_uri", NULL);
  3796. if (nsuri)
  3797. outf("\trpc_resp.set_nsuri(%s);\n\n", nsuri);
  3798. else
  3799. {
  3800. outs("\tStringBuffer nsuri;\n");
  3801. outs("\tnsuri.append(\"urn:hpccsystems:ws:\").appendLower(m_serviceName.length(), m_serviceName.str());\n");
  3802. outs("\trpc_resp.set_nsuri(nsuri.str());\n\n");
  3803. }
  3804. int soap_encode = getMetaInt("soap_encode", -1);
  3805. if (soap_encode ==-1)
  3806. soap_encode = getMetaInt("encode", 1);
  3807. if (soap_encode==0)
  3808. outs("\trpc_resp.setEncodeXml(false);\n");
  3809. if (espm_type_==espm_response)
  3810. {
  3811. outs(
  3812. "\tconst IMultiException& exceptions = getExceptions();\n"
  3813. "\tif (exceptions.ordinality() > 0)\n"
  3814. "\t{\n"
  3815. "\t\tStringBuffer xml;\n"
  3816. "\t\texceptions.serialize(xml, 0, true, false);\n"
  3817. "\t\trpc_resp.add_value(\"\", \"\", \"Exceptions\", \"\", xml.str(), false);\n"
  3818. "\t}\n"
  3819. "\telse\n"
  3820. "\t{\n");
  3821. }
  3822. //attributes first
  3823. int attrCount=0;
  3824. for (pi=getParams();pi!=NULL;pi=pi->next)
  3825. {
  3826. if (pi->getMetaInt("attribute"))
  3827. {
  3828. attrCount++;
  3829. if (attrCount==1)
  3830. outs(1, "Owned<IProperties> props=createProperties();\n");
  3831. outf(1, "if (!m_%s.is_nil())\n", pi->name);
  3832. outf(2, "props->setProp(\"%s\", m_%s.getValue());\n", pi->getXmlTag(), pi->name);
  3833. }
  3834. }
  3835. if (attrCount!=0)
  3836. outs(1, "rpc_resp.add_attr(NULL, NULL, NULL, *props.get());\n");
  3837. for (pi=getParams();pi!=NULL;pi=pi->next)
  3838. {
  3839. pi->write_esp_marshall(true, true, true, (espm_type_==espm_response)?2:1);
  3840. }
  3841. if (espm_type_==espm_response)
  3842. outs("\t}\n");
  3843. outs("}\n\n");
  3844. //method ==> copy
  3845. outf("\nvoid C%s::copy(C%s &from)\n{\n", name_, name_);
  3846. if (parent)
  3847. {
  3848. outf(1, "C%s *baseFrom = static_cast<C%s*>(&from);\n", parent, parent);
  3849. outf(2, "C%s::copy(*baseFrom);\n", parent);
  3850. }
  3851. for (pi=getParams();pi!=NULL;pi=pi->next)
  3852. outf("\tm_%s.copy(from.m_%s);\n", pi->name, pi->name);
  3853. if (getMetaInt("element"))
  3854. outf("\tset_tag_value(from.get_tag_value());\n");
  3855. outs("}\n\n");
  3856. //method ==> copy from interface
  3857. outf("\nvoid C%s::copy(IConst%s &ifrom)\n{\n", name_, name_);
  3858. if (parent)
  3859. {
  3860. outf(1, "C%s *classFrom = static_cast<C%s*>(&ifrom);\n", name_, name_);
  3861. outf(1, "IConst%s *baseICFrom = static_cast<IConst%s*>(classFrom);\n", parent, parent);
  3862. outf(2, "C%s::copy(*baseICFrom);\n", parent);
  3863. }
  3864. for (pi=getParams();pi!=NULL;pi=pi->next)
  3865. {
  3866. char *uname=strdup(pi->name);
  3867. *uname=upperchar(*uname);
  3868. outf("\tset%s(ifrom.get%s());\n", uname, uname);
  3869. free(uname);
  3870. }
  3871. if (getMetaInt("element"))
  3872. outf("\tset_tag_value(ifrom.get_tag_value());\n");
  3873. outs("}\n\n");
  3874. //method ==> getAttributes (IProperties &attributes)
  3875. outf("\nvoid C%s::getAttributes(IProperties &attributes)\n{\n", name_);
  3876. for (pi=getParams(); pi!=NULL; pi=pi->next)
  3877. {
  3878. if (pi->getMetaInt("attribute"))
  3879. outf(2, "attributes.setProp(\"%s\", m_%s.getValue());\n", pi->getXmlTag(), pi->name);
  3880. }
  3881. outs("}\n\n");
  3882. //method ==> serializeContent (StringBuffer&)
  3883. outf("\nvoid C%s::serializeContent(IEspContext* ctx, StringBuffer& buffer, IProperties **pprops)\n{\n", name_);
  3884. int http_encode = getMetaInt("http_encode", -1);
  3885. if (http_encode ==-1)
  3886. http_encode = getMetaInt("encode", 1);
  3887. bool encodeXML = http_encode==1;
  3888. if (espm_type_==espm_response)
  3889. {
  3890. outs(
  3891. "\tconst IMultiException& exceptions = getExceptions();\n"
  3892. "\tif (exceptions.ordinality() > 0)\n"
  3893. "\t{\n"
  3894. "\t\tif(ctx && ctx->getResponseFormat()==ESPSerializationJSON)\n"
  3895. "\t\t\texceptions.serializeJSON(buffer, 0, true);\n"
  3896. "\t\telse\n"
  3897. "\t\t\texceptions.serialize(buffer, 0, true);\n"
  3898. "\t}\n"
  3899. "\telse\n"
  3900. "\t{\n");
  3901. if (parent)
  3902. outf("\t\tC%s::serializeContent(ctx,buffer);\n", parent);
  3903. if (hasMapInfo())
  3904. outf("\t\tdouble clientVer = ctx ? ctx->getClientVersion() : -1;\n");
  3905. bool encodeJSON = true;
  3906. const char * name = getName();
  3907. unsigned nameLength = strlen(name);
  3908. if (nameLength >= 2)
  3909. {
  3910. const char * nameEnding = &name[nameLength - 2];
  3911. bool isResponseEx = strcmp(nameEnding, "Ex") == 0;
  3912. encodeJSON = !(isResponseEx && (stricmp(getParams()->getXmlTag(), "Response") == 0));
  3913. }
  3914. for (pi=getParams();pi!=NULL;pi=pi->next)
  3915. {
  3916. if (!pi->getMetaInt("attribute"))
  3917. pi->write_esp_marshall(false, encodeXML, true, 2, encodeJSON);
  3918. }
  3919. outs("\t}\n");
  3920. }
  3921. else
  3922. {
  3923. if (parent)
  3924. outf("\tC%s::serializeContent(ctx,buffer);\n", parent);
  3925. if (hasMapInfo())
  3926. outf("\tdouble clientVer = ctx ? ctx->getClientVersion() : -1;\n");
  3927. //attributes first
  3928. int attrCount=0;
  3929. for (pi=getParams();pi!=NULL;pi=pi->next)
  3930. {
  3931. if (pi->getMetaInt("attribute"))
  3932. {
  3933. attrCount++;
  3934. if (attrCount==1)
  3935. {
  3936. outs(1, "if (pprops)\n");
  3937. outs(1, "{\n");
  3938. outs(2, "*pprops=NULL;\n");
  3939. }
  3940. outf(2, "if (!m_%s.is_nil())\n", pi->name);
  3941. outs(2, "{\n");
  3942. outs(3, "if (!*pprops)\n");
  3943. outs(4, "*pprops=createProperties();\n");
  3944. outf(3, "(*pprops)->setProp(\"%s\", m_%s.getValue());\n", pi->getXmlTag(), pi->name);
  3945. outs(2, "}\n");
  3946. }
  3947. }
  3948. if (attrCount!=0)
  3949. outs(1, "}\n");
  3950. for (pi=getParams();pi!=NULL;pi=pi->next)
  3951. {
  3952. if (!pi->getMetaInt("attribute"))
  3953. pi->write_esp_marshall(false, encodeXML, true);
  3954. }
  3955. if (getMetaInt("element")!=0)
  3956. {
  3957. outs(1, "if (m_tag_value.length()) {\n");
  3958. outs(2, "StringBuffer encoded;\n");
  3959. outs(2, "encodeXML(m_tag_value, encoded);\n");
  3960. outs(2, "buffer.append(encoded);\n");
  3961. outs(1, "}\n");
  3962. }
  3963. }
  3964. outs("}\n\n");
  3965. //method ==> serialize (StringBuffer&)
  3966. outf("\nvoid C%s::serializeAttributes(IEspContext* ctx, StringBuffer& s)\n{\n", name_);
  3967. for (pi=getParams();pi!=NULL;pi=pi->next)
  3968. {
  3969. if (pi->getMetaInt("attribute"))
  3970. {
  3971. outf(1, "if (!m_%s.is_nil()) {\n", pi->name);
  3972. outf(2, "StringBuffer enc;\n");
  3973. outf(2, "encodeXML(m_%s.getValue(), enc);\n", pi->name);
  3974. outf(2, "s.appendf(\" %s=\\\"%%s\\\"\", enc.str());\n", pi->getXmlTag());
  3975. outf(1, "}\n");
  3976. }
  3977. }
  3978. outs("}\n");
  3979. //method ==> serializer(IEspContext* ctx, ..., StringBuffer&, ...)
  3980. outf("\nvoid C%s::serializer(IEspContext* ctx, IConst%s &src, StringBuffer& buffer, bool keepRootTag)\n{\n", name_, name_);
  3981. // attributes
  3982. int nAttrs = 0;
  3983. for (pi=getParams();pi!=NULL;pi=pi->next)
  3984. if (pi->getMetaInt("attribute"))
  3985. nAttrs++;
  3986. if (nAttrs)
  3987. {
  3988. outf(1,"if (keepRootTag)\n\t{\n");
  3989. outf(2,"buffer.append(\"<%s\");\n", name_);
  3990. for (pi=getParams();pi!=NULL;pi=pi->next)
  3991. {
  3992. if (pi->getMetaInt("attribute"))
  3993. {
  3994. char* fname = getFieldName(pi->name);
  3995. outf(2, "%sattr = src.get%s();\n", (pi==getParams())?"const char* ":"", fname);
  3996. free(fname);
  3997. outf(2, "if (attr && *attr) {\n");
  3998. outf(3, "StringBuffer encoded;\n");
  3999. outf(3, "encodeXML(attr,encoded);\n");
  4000. outf(3, "buffer.appendf(\" %s=\\\"%%s\\\"\",encoded.str());\n", pi->getXmlTag());
  4001. outf(2, "}\n");
  4002. }
  4003. }
  4004. outf(2,"buffer.append(\">\");\n");
  4005. outf(1,"}\n");
  4006. }
  4007. else
  4008. outf(1,"if (keepRootTag)\n\tbuffer.append(\"<%s>\");\n", name_);
  4009. if (parent)
  4010. {
  4011. outf(1, "C%s *classSrc = static_cast<C%s*>(&src);\n", name_, name_);
  4012. outf(1, "C%s *baseSrc = static_cast<C%s*>(classSrc);\n", parent, parent);
  4013. outf(2, "C%s::serializer(ctx, *baseSrc, buffer, false);\n",parent);
  4014. }
  4015. // -- versioning
  4016. if (hasMapInfo())
  4017. {
  4018. outf("\tdouble clientVer = ctx ? ctx->getClientVersion() : -1;\n");
  4019. }
  4020. #if 1
  4021. // not respecting nil_remove: backward compatible
  4022. for (pi=getParams();pi!=NULL;pi=pi->next)
  4023. {
  4024. if (pi->getMetaInt("attribute"))
  4025. continue;
  4026. outf("\t// field %s\n", pi->name);
  4027. char *uname=getFieldName(pi->name);
  4028. bool hasIf = false;
  4029. if (pi->hasMapInfo())
  4030. hasIf = pi->write_mapinfo_check(1,"ctx");
  4031. //if (hasIf) outs("\t{\n");
  4032. const char* ifIndent = hasIf?"\t":"";
  4033. if (pi->flags & PF_TEMPLATE) // array
  4034. {
  4035. outf("\t{\n");
  4036. if (pi->isPrimitiveArray())
  4037. {
  4038. const char *item_tag = pi->getMetaString("item_tag", "Item");
  4039. const char *type = pi->getArrayImplType();
  4040. outf("\t\t%s& v = src.get%s();\n",type,uname);
  4041. outf("\t\tif (v.length()>0)\n");
  4042. outf("\t\t\tbuffer.append(\"<%s>\");\n", pi->getXmlTag());
  4043. outf("\t\tfor (size32_t i=0;i<v.length();i++)\n");
  4044. const char* fmt = "%"; // print %% when undefined
  4045. switch(pi->kind)
  4046. {
  4047. case TK_BOOL:
  4048. case TK_SHORT:
  4049. case TK_INT: fmt = "d"; break;
  4050. case TK_UNSIGNED: fmt = "u"; break;
  4051. case TK_LONG: fmt = "ld"; break;
  4052. case TK_UNSIGNEDLONG: fmt = "lu"; break;
  4053. case TK_FLOAT:
  4054. case TK_DOUBLE: fmt = "g"; break;
  4055. case TK_null:
  4056. case TK_CHAR: fmt = "s"; break;
  4057. default:
  4058. {
  4059. char buf[128];
  4060. sprintf(buf,"Unhandled array type: %s (%s)", getTypeKindName(pi->kind), name_);
  4061. yyerror(buf);
  4062. }
  4063. }
  4064. outf("\t\t\tbuffer.appendf(\"<%s>%%%s</%s>\",v.item(i));\n",item_tag,fmt,item_tag);
  4065. outf("\t\tif (v.length()>0)\n");
  4066. outf("\t\t\tbuffer.append(\"</%s>\");\n", pi->getXmlTag());
  4067. }
  4068. else if (pi->typname)
  4069. {
  4070. if (pi->kind == TK_ESPENUM)
  4071. {
  4072. outf("\t\t%sArray& v = src.get%s();\n",pi->typname,uname);
  4073. outf("\t\tint size = v.length();\n");
  4074. const char *item_tag = pi->getMetaString("item_tag", "Item");
  4075. outf("\t\tif (size>0)\n");
  4076. outf("\t\t\tbuffer.append(\"<%s>\");\n", pi->getXmlTag());
  4077. outf("\t\tfor (int i=0;i<size;i++)\n");
  4078. //outf("\t\t{\n");
  4079. outf("\t\t\tbuffer.appendf(\"<%s>%%s</%s>\", CX%s::stringOf(v.item(i)));\n",item_tag, item_tag, pi->typname);
  4080. //outf("\t\t\tC%s::serializer(ctx,v.item(i),buffer,false);\n",pi->typname);
  4081. //outf("\t\t\tbuffer.append(\"</%s>\");\n",item_tag);
  4082. //outf("\t\t}\n");
  4083. outf("\t\tif (size>0)\n");
  4084. outf("\t\t\tbuffer.append(\"</%s>\");\n", pi->getXmlTag());
  4085. }
  4086. else if (pi->kind == TK_ESPSTRUCT || pi->kind == TK_null) // should be fixed at lex/yacc
  4087. {
  4088. outf("\t\tIArrayOf<IConst%s>& v = src.get%s();\n",pi->typname,uname);
  4089. outf("\t\tint size = v.length();\n");
  4090. const char *item_tag = pi->getMetaString("item_tag", "Item");
  4091. outf("\t\tif (size>0)\n");
  4092. outf("\t\t\tbuffer.append(\"<%s>\");\n", pi->getXmlTag());
  4093. outf("\t\tfor (int i=0;i<size;i++)\n");
  4094. outf("\t\t{\n");
  4095. outf("\t\t\tbuffer.append(\"<%s>\");\n",item_tag);
  4096. outf("\t\t\tC%s::serializer(ctx,v.item(i),buffer,false);\n",pi->typname);
  4097. outf("\t\t\tbuffer.append(\"</%s>\");\n",item_tag);
  4098. outf("\t\t}\n");
  4099. outf("\t\tif (size>0)\n");
  4100. outf("\t\t\tbuffer.append(\"</%s>\");\n", pi->getXmlTag());
  4101. }
  4102. else
  4103. outf("\t\t**** TODO: unhandled array: kind=%s, type=%s, name=%s, xsd-type=%s\n", getTypeKindName(pi->kind), pi->typname, uname, pi->getXsdType());
  4104. }
  4105. else
  4106. {
  4107. outf("\t\t**** TODO: unhandled array: type=<NULL>, name=%s, xsd-type=%s\n", uname, pi->getXsdType());
  4108. }
  4109. outf("\t}\n");
  4110. }
  4111. else if (pi->kind == TK_ESPSTRUCT)
  4112. {
  4113. outf("\t{\n");
  4114. outf("\t\tStringBuffer tmp;\n");
  4115. outf("\t\tC%s::serializer(ctx,src.get%s(), tmp, false);\n", pi->typname, uname);
  4116. outf("\t\tif (tmp.length()>0)\n");
  4117. const char* tag = pi->getXmlTag();
  4118. outf("\t\t\tbuffer.appendf(\"<%s>%%s</%s>\",tmp.str());\n", tag, tag);
  4119. outf("\t}\n");
  4120. }
  4121. else if (pi->kind == TK_ESPENUM)
  4122. {
  4123. outs("\t{\n");
  4124. outf("\t\tconst char* s = src.get%sAsString();\n",uname);
  4125. outf("\t\tbuffer.append(\"<%s>\");\n",pi->getXmlTag());
  4126. outs("\t\tencodeUtf8XML(s,buffer);\n");
  4127. outf("\t\tbuffer.append(\"</%s>\");\n",pi->getXmlTag());
  4128. outs("\t}\n");
  4129. }
  4130. else
  4131. {
  4132. esp_xlate_info* info = esp_xlat(pi);
  4133. switch(info->access_kind)
  4134. {
  4135. case TK_CHAR:
  4136. outf("\t{\n");
  4137. outf("\t\tconst char* s = src.get%s();\n", uname);
  4138. outf("\t\tif (s && *s)\n");
  4139. if (!getMetaInt("encode",1))
  4140. {
  4141. outf("\t\tbuffer.appendf(\"<%s>%%s</%s>\",s);\n",pi->name,pi->name);
  4142. }
  4143. else
  4144. {
  4145. outf("\t\t{\n");
  4146. outf("\t\t\tbuffer.append(\"<%s>\");\n", pi->getXmlTag());
  4147. outf("\t\t\tencodeUtf8XML(s,buffer);\n");
  4148. outf("\t\t\tbuffer.append(\"</%s>\");\n", pi->getXmlTag());
  4149. outf("\t\t}\n");
  4150. }
  4151. outf("\t}\n");
  4152. break;
  4153. case TK_INT:
  4154. case TK_SHORT:
  4155. {
  4156. outf("\t{\n");
  4157. outf("\t\t%s n = src.get%s();\n", esp_xlat(pi)->access_type, uname);
  4158. outf("\t\tif (n)\n");
  4159. const char* tag = pi->getXmlTag();
  4160. outf("\t\t\tbuffer.appendf(\"<%s>%%d</%s>\", n);\n", tag, tag);
  4161. outf("\t}\n");
  4162. break;
  4163. }
  4164. case TK_LONG:
  4165. {
  4166. outf("\t{\n");
  4167. outf("\t\t%s n = src.get%s();\n", esp_xlat(pi)->access_type, uname);
  4168. outf("\t\tif (n)\n");
  4169. const char* tag = pi->getXmlTag();
  4170. outf("\t\t\tbuffer.appendf(\"<%s>%%\" I64F \"d</%s>\", n);\n", tag, tag);
  4171. outf("\t}\n");
  4172. break;
  4173. }
  4174. case TK_BOOL:
  4175. {
  4176. outf("\t{\n");
  4177. outf("\t\t%s b = src.get%s();\n", esp_xlat(pi)->access_type, uname);
  4178. outf("\t\tif (b)\n");
  4179. const char* tag = pi->getXmlTag();
  4180. outf("\t\t\tbuffer.appendf(\"<%s>1</%s>\");\n", tag, tag);
  4181. outf("\t}\n");
  4182. break;
  4183. }
  4184. default:
  4185. if (pi->kind == TK_STRUCT && info->eam_type == EAM_jmbin) // binary
  4186. {
  4187. //TODO: should we encode binary data?
  4188. outf("\t{\n");
  4189. outf("\t\tStringBuffer tmp;\n");
  4190. outf("\t\tJBASE64_Encode(src.get%s().toByteArray(), src.get%s().length(), tmp, true);\n", uname, uname);
  4191. outf("\t\tif (tmp.length()>0)\n");
  4192. const char* tag = pi->getXmlTag();
  4193. outf("\t\t\tbuffer.appendf(\"<%s>%%s</%s>\",tmp.str());\n", tag, tag);
  4194. outf("\t}\n");
  4195. }
  4196. else
  4197. {
  4198. outf("\t{\n");
  4199. outf("\t\t//*** default kind: %s; type=%s, name=%s\n", getTypeKindName(pi->kind), pi->typname, uname);
  4200. outf("\t\tbuffer.append(\"<%s>\");\n", pi->getXmlTag());
  4201. outf("\t\tbuffer.append(src.get%s());\n", uname);
  4202. outf("\t\tbuffer.append(\"</%s>\");\n", pi->getXmlTag());
  4203. outf("\t}\n");
  4204. }
  4205. break;
  4206. }
  4207. }
  4208. //if (hasIf) outs("\t}\n");
  4209. free(uname);
  4210. }
  4211. #else
  4212. // respect nil_remove: may cause backward compatibility problem
  4213. bool nilRemove = getMetaInt("nil_remove", 0)!=0;
  4214. indentReset(1);
  4215. for (pi=getParams();pi!=NULL;pi=pi->next)
  4216. {
  4217. char *uname=strdup(pi->name);
  4218. *uname = upperchar(*uname);
  4219. if (pi->hasMapInfo())
  4220. pi->write_mapinfo_check(1,"ctx");
  4221. if (pi->flags & PF_TEMPLATE) // array
  4222. {
  4223. indentOutf("{\n");
  4224. indentInc(1);
  4225. if (pi->isPrimitiveArray())
  4226. {
  4227. const char *item_tag = pi->getMetaString("item_tag", "Item");
  4228. const char *type = pi->getArrayImplType();
  4229. indentOutf("%s& v = src.get%s();\n",type,uname);
  4230. indentOutf("int size = v.length();\n");
  4231. if (nilRemove)
  4232. {
  4233. indentOutf("if (size>0)\n");
  4234. indentOutf1(1,"buffer.append(\"<%s>\");\n", pi->getXmlTag());
  4235. }
  4236. else
  4237. indentOutf("buffer.append(\"<%s>\");\n", pi->getXmlTag());
  4238. indentOuts("for (int i=0;i<size;i++)\n");
  4239. const char* fmt;
  4240. switch(pi->kind)
  4241. {
  4242. case TK_BOOL:
  4243. case TK_SHORT:
  4244. case TK_INT: fmt = "d"; break;
  4245. case TK_UNSIGNED: fmt = "u"; break;
  4246. case TK_LONG: fmt = "ld"; break;
  4247. case TK_UNSIGNEDLONG: fmt = "lu"; break;
  4248. case TK_FLOAT:
  4249. case TK_DOUBLE: fmt = "g"; break;
  4250. case TK_null:
  4251. case TK_CHAR: fmt = "s"; break;
  4252. default:
  4253. {
  4254. char buf[128];
  4255. sprintf(buf,"Unhandled array type: %s (%s)", getTypeKindName(pi->kind), name_);
  4256. yyerror(buf);
  4257. }
  4258. }
  4259. indentOutf1(1,"buffer.appendf(\"<%s>%%%s</%s>\",v.item(i));\n",item_tag,fmt,item_tag);
  4260. if (nilRemove)
  4261. {
  4262. indentOutf("if (size>0)\n");
  4263. indentOutf1(1,"buffer.append(\"</%s>\");\n", pi->getXmlTag());
  4264. }
  4265. else
  4266. indentOutf("buffer.append(\"</%s>\");\n", pi->getXmlTag());
  4267. }
  4268. else if (pi->typname)
  4269. {
  4270. indentOutf("IArrayOf<IConst%s>& v = src.get%s();\n",pi->typname,uname);
  4271. indentOuts("int size = v.length();\n");
  4272. const char *item_tag = pi->getMetaString("item_tag", pi->typname);
  4273. if (nilRemove)
  4274. {
  4275. indentOutf("if (size>0)\n");
  4276. indentOutf1(1,"buffer.append(\"<%s>\");\n", pi->getXmlTag());
  4277. }
  4278. else
  4279. indentOutf("buffer.append(\"<%s>\");\n", pi->getXmlTag());
  4280. indentOutf("for (int i=0;i<size;i++)\n");
  4281. indentOutf("{\n");
  4282. indentOutf(1,"buffer.append(\"<%s>\");\n",item_tag);
  4283. indentOutf("C%s::serializer(ctx,v.item(i),buffer,false);\n",pi->typname);
  4284. indentOutf("buffer.append(\"</%s>\");\n",item_tag);
  4285. indentOutf(-1,"}\n");
  4286. if (nilRemove)
  4287. {
  4288. indentOutf("if (size>0)\n");
  4289. indentOutf1(1,"buffer.append(\"</%s>\");\n", pi->getXmlTag());
  4290. }
  4291. else
  4292. indentOutf("buffer.append(\"</%s>\");\n", pi->getXmlTag());
  4293. }
  4294. else
  4295. {
  4296. indentOutf("**** TODO: unhandled array: type=%s, name=%s, xsd-type=%s\n", pi->typname, uname, pi->getXsdType());
  4297. }
  4298. indentOutf(-1,"}\n");
  4299. }
  4300. else if (pi->kind == TK_ESPSTRUCT)
  4301. {
  4302. indentOutf("{\n");
  4303. indentInc(1);
  4304. if (nilRemove)
  4305. {
  4306. indentOutf("StringBuffer tmp;\n");
  4307. indentOutf("C%s::serializer(ctx,src.get%s(), tmp, false);\n", pi->typname, uname);
  4308. indentOutf("if (tmp.length()>0)\n");
  4309. const char* tag = pi->getXmlTag();
  4310. indentOutf1(1,"buffer.appendf(\"<%s>%%s</%s>\",tmp.str());\n", tag, tag);
  4311. }
  4312. else
  4313. {
  4314. indentOutf("buffer.append(\"<%s>\");\n", pi->getXmlTag());
  4315. indentOutf("C%s::serializer(ctx,src.get%s(), buffer, false);\n", pi->typname, uname);
  4316. indentOutf("buffer.append(\"</%s>\");\n", pi->getXmlTag());
  4317. }
  4318. indentOutf(-1,"}\n");
  4319. }
  4320. else
  4321. {
  4322. esp_xlate_info* info = esp_xlat(pi);
  4323. switch(info->access_kind)
  4324. {
  4325. case TK_CHAR:
  4326. indentOuts("{\n");
  4327. indentOutf(1,"const char* s = src.get%s();\n", uname);
  4328. if (nilRemove)
  4329. {
  4330. indentOutf("if (s && *s)\n");
  4331. indentInc(1);
  4332. }
  4333. if (!getMetaInt("encode",1))
  4334. {
  4335. indentOutf("buffer.appendf(\"<%s>%%s</%s>\",s);\n",pi->name,pi->name);
  4336. }
  4337. else
  4338. {
  4339. if (nilRemove)
  4340. indentOutf1(-1,"{\n");
  4341. indentOutf("buffer.append(\"<%s>\");\n", pi->getXmlTag());
  4342. indentOutf("encodeUtf8XML(s,buffer);\n");
  4343. indentOutf("buffer.append(\"</%s>\");\n", pi->getXmlTag());
  4344. if (nilRemove)
  4345. indentOutf1(-1,"}\n");
  4346. }
  4347. if (nilRemove)
  4348. indentInc(-1);
  4349. indentOuts(-1,"}\n");
  4350. break;
  4351. case TK_INT:
  4352. case TK_LONG:
  4353. case TK_SHORT:
  4354. indentOuts("{\n");
  4355. indentOutf(1,"%s n = src.get%s();\n", esp_xlat(pi)->access_type, uname);
  4356. if (nilRemove)
  4357. {
  4358. indentOuts("if (n)\n");
  4359. indentInc(1);
  4360. }
  4361. indentOutf("buffer.appendf(\"<%s>%%d</%s>\", n);\n", pi->name,pi->name);
  4362. if (nilRemove)
  4363. indentInc(-1);
  4364. indentOuts(-1,"}\n");
  4365. break;
  4366. case TK_BOOL:
  4367. indentOuts("{\n");
  4368. indentOutf(1,"%s b = src.get%s();\n", esp_xlat(pi)->access_type, uname);
  4369. if (nilRemove)
  4370. {
  4371. indentOuts("if (b)\n");
  4372. indentInc(1);
  4373. }
  4374. const char* tag = pi->getXmlTag();
  4375. indentOutf("buffer.append(\"<%s>1</%s>\");\n", tag,tag);
  4376. if (nilRemove)
  4377. indentInc(-1);
  4378. indentOuts(-1,"}\n");
  4379. break;
  4380. default:
  4381. if (pi->kind == TK_STRUCT && info->eam_type == EAM_jmbin) // binary
  4382. {
  4383. //TODO: should we encode binary data?
  4384. indentOuts("{\n");
  4385. if (nilRemove)
  4386. {
  4387. indentOutf(1,"StringBuffer tmp;\n");
  4388. indentOutf("JBASE64_Encode(src.get%s().toByteArray(), src.get%s().length(), tmp, true);\n", uname, uname);
  4389. indentOutf("if (tmp.length()>0)\n");
  4390. const char* tag = pi->getXmlTag();
  4391. indentOutf1(1,"buffer.appendf(\"<%s>%%s</%s>\",tmp.str());\n", tag,tag);
  4392. }
  4393. else
  4394. {
  4395. indentOutf(1,"buffer.append(\"<%s>\");\n", pi->getXmlTag());
  4396. indentOutf("JBASE64_Encode(src.get%s().toByteArray(), src.get%s().length(), buffer, ture);\n", uname, uname);
  4397. indentOutf("buffer.append(\"</%s>\");\n", pi->getXmlTag());
  4398. }
  4399. indentOuts(-1,"}\n");
  4400. }
  4401. else
  4402. {
  4403. indentOuts("{\n");
  4404. if (nilRemove)
  4405. {
  4406. indentOutf(1,"//*** default kind: %s; type=%s, name=%s\n", getTypeKindName(pi->kind), pi->typname, uname);
  4407. indentOutf("StringBuffer tmp(src.get%s());\n",uname);
  4408. indentOutf("if (tmp.length()>0)\n");
  4409. indentOutf1(1,"buffer.appendf(\"<%s>%%s</%s>\",tmp.str());\n", pi->name,pi->name);
  4410. }
  4411. else
  4412. {
  4413. indentOutf(1,"//*** default kind: %s; type=%s, name=%s\n", getTypeKindName(pi->kind), pi->typname, uname);
  4414. indentOutf("buffer.append(\"<%s>\");\n", pi->getXmlTag());
  4415. indentOutf("buffer.append(src.get%s());\n", uname);
  4416. indentOutf("buffer.append(\"</%s>\");\n", pi->getXmlTag());
  4417. }
  4418. indentOuts(-1,"}\n");
  4419. }
  4420. break;
  4421. }
  4422. }
  4423. free(uname);
  4424. }
  4425. #endif
  4426. outf("\tif (keepRootTag)\n\t\tbuffer.append(\"</%s>\");\n", name_);
  4427. outs("}\n");
  4428. //=============================================================================================================
  4429. //method ==> serialize (MemoryBuffer&, StringBuffer &)
  4430. if (contentVar)
  4431. {
  4432. outf("\nvoid C%s::appendContent(IEspContext* ctx, MemoryBuffer& buffer, StringBuffer &mimetype)\n{\n", name_);
  4433. esp_xlate_info *xinfo = esp_xlat(contentVar);
  4434. if (strcmp(xinfo->store_type, "StringBuffer")!=0)
  4435. outf("\tbuffer.clear().append(m_%s.getValue());\n", contentVar->name);
  4436. else
  4437. outf("\tbuffer.clear().append(m_%s.getValue().length(), m_%s.getValue().str());\n", contentVar->name, contentVar->name);
  4438. outf("\tmimetype.set(m_%s_mimetype.str());\n", contentVar->name);
  4439. outs("}\n");
  4440. }
  4441. //=============================================================================================================
  4442. //method: unserialize(IRcpMessage...)
  4443. outf("\nbool C%s::unserialize(IRpcMessage& rpc_request, const char *tagname, const char *basepath)\n{\n", name_);
  4444. if (parent)
  4445. {
  4446. outf("\tbool hasValue = C%s::unserialize(rpc_request, tagname, basepath);\n", parent);
  4447. outf("\treturn hasValue | localUnserialize(rpc_request, tagname, basepath);\n");
  4448. outs("}\n");
  4449. //method: localUnserialize(IRcpMessage...)
  4450. outf("\nbool C%s::localUnserialize(IRpcMessage& rpc_request, const char *tagname, const char *basepath)\n{\n", name_);
  4451. }
  4452. outs("\trpc_request.setEncodeXml(false);\n");
  4453. outs("\tbool hasValue = false;\n");
  4454. if (espm_type_==espm_response)
  4455. {
  4456. outs(
  4457. "\tStringBuffer xml;\n"
  4458. "\trpc_request.get_value(\"Exceptions\", xml, false);\n\n"
  4459. "\tOwned<IMultiException> me = MakeMultiException();\n"
  4460. "\tif(xml.length() > 0)\n"
  4461. "\t\tme->deserialize(xml.str());\n\n"
  4462. "\tif (me->ordinality() > 0 )\n"
  4463. "\t{\n"
  4464. "\t\tIArrayOf<IException>& exceptions = me->getArray();\n"
  4465. "\t\tForEachItemIn(i, exceptions)\n"
  4466. "\t\t\tnoteException(*LINK(&exceptions.item(i)));\n"
  4467. "\t}\n"
  4468. "\telse\n"
  4469. "\t{\n");
  4470. }
  4471. for (pi=getParams();pi!=NULL;pi=pi->next)
  4472. {
  4473. pi->write_esp_unmarshall("rpc_request", true, (espm_type_==espm_response)?2:1);
  4474. }
  4475. if (getMetaInt("element"))
  4476. {
  4477. outs(1, "hasValue |= rpc_request.get_value(basepath, m_tag_value);\n");
  4478. }
  4479. if (espm_type_==espm_response)
  4480. outs("\t}\n");
  4481. outs("\treturn hasValue;\n");
  4482. outs("}\n");
  4483. //=============================================================================================================
  4484. //method: unserialize(CSoapValue...)
  4485. if (parent)
  4486. {
  4487. outf("\nbool C%s::unserialize(IEspContext* ctx, CSoapValue& soapval, bool localOnly)\n{\n", name_);
  4488. outf("\tbool hasValue = false;\n");
  4489. outf("\tif(!localOnly)\n");
  4490. outf("\t\thasValue |= C%s::unserialize(ctx,soapval);\n", parent);
  4491. }
  4492. else
  4493. {
  4494. outf("\nbool C%s::unserialize(IEspContext* ctx, CSoapValue& soapval)\n{\n", name_);
  4495. outf("\tbool hasValue = false;\n");
  4496. }
  4497. for (pi=getParams();pi!=NULL;pi=pi->next)
  4498. {
  4499. pi->write_esp_unmarshall_soapval("soapval");
  4500. }
  4501. if (getMetaInt("element"))
  4502. outs(1, "hasValue |= soapval.get_value(\"\",m_tag_value);\n");
  4503. outs("\treturn hasValue;\n");
  4504. outs("}\n");
  4505. //=============================================================================================================
  4506. //method: unserialize(IProperties...)
  4507. if (parent)
  4508. {
  4509. outf("\nbool C%s::unserialize(IEspContext* ctx, IProperties& params, MapStrToBuf *attachments, const char *basepath, bool localOnly)\n{\n", name_);
  4510. outf("\tbool hasValue = false;\n");
  4511. outf("\tif(!localOnly)\n");
  4512. outf("\t\thasValue |= C%s::unserialize(ctx,params,attachments, basepath);\n", parent);
  4513. }
  4514. else
  4515. {
  4516. outf("\nbool C%s::unserialize(IEspContext* ctx, IProperties& params, MapStrToBuf *attachments, const char *basepath)\n{\n", name_);
  4517. outf("\tbool hasValue = false;\n");
  4518. }
  4519. for (pi=getParams();pi!=NULL;pi=pi->next)
  4520. {
  4521. if (pi->typname && !strcmp(pi->typname, "EspTextFile"))
  4522. {
  4523. pi->write_esp_unmarshall_attachments("params", "attachments");
  4524. indent(1);
  4525. outf("hasValue |= m_%s_name.unmarshall(ctx, params, attachments, \"%s\", basepath%s);\n", pi->name, pi->name, pi->getOptionalParam());
  4526. }
  4527. else
  4528. pi->write_esp_unmarshall_properties("params", "attachments");;
  4529. }
  4530. if (getMetaInt("element"))
  4531. {
  4532. outs(1, "const char* val = params.queryProp(basepath);\n");
  4533. outs(1, "if (val && *val) {\n");
  4534. outs(2, "m_tag_value.set(val);\n");
  4535. outs(2, "hasValue = true;\n");
  4536. outs(1, "}\n");
  4537. }
  4538. outs("\treturn hasValue;\n");
  4539. outs("}\n");
  4540. //outf("\n\tvoid C%s::unserialize(const char * msg)\n\t{\n", name_);
  4541. //for (pi=getParams();pi!=NULL;pi=pi->next)
  4542. //{
  4543. // pi->write_esp_unmarshall("msg");
  4544. //}
  4545. //outs("\t}\n\n");
  4546. outs("\n");
  4547. write_esp_methods();
  4548. //outs("};\n\n");
  4549. write_factory_impl();
  4550. }
  4551. void EspMessageInfo::write_clarion_methods(enum espaxm_type axstype)
  4552. {
  4553. ParamInfo *pi;
  4554. if (axstype!=espaxm_setters)
  4555. {
  4556. if (espm_type_==espm_response)
  4557. outs("queryClientStatus PROCEDURE(),LONG,PROC\n");
  4558. for (pi=getParams();pi!=NULL;pi=pi->next)
  4559. {
  4560. pi->write_clarion_attr_method(false);
  4561. }
  4562. }
  4563. if (axstype!=espaxm_getters)
  4564. {
  4565. for (pi=getParams();pi!=NULL;pi=pi->next)
  4566. {
  4567. pi->write_clarion_attr_method(true);
  4568. }
  4569. }
  4570. }
  4571. void EspMessageInfo::write_esp_mapinfo(bool isDecl)
  4572. {
  4573. #ifdef MAP_INFO
  4574. outs("\nstatic IEspMapInfo& getMapInfo();");
  4575. #endif
  4576. }
  4577. char* makeXsdType(const char* s)
  4578. {
  4579. if (!s)
  4580. return NULL;
  4581. if (*s == '"')
  4582. s++;
  4583. if (strncmp(s,"tns:",4)==0)
  4584. {
  4585. s+=4;
  4586. size_t len = strlen(s);
  4587. if (*(s+len-1)=='"')
  4588. len--;
  4589. char* t = (char*)malloc(len+1);
  4590. memcpy(t,s,len);
  4591. t[len] = 0;
  4592. return t;
  4593. }
  4594. else
  4595. return NULL;
  4596. }
  4597. void EspMessageInfo::write_esp_methods(enum espaxm_type axstype, bool isDecl, bool isPure)
  4598. {
  4599. ParamInfo *pi;
  4600. if (axstype!=espaxm_setters)
  4601. {
  4602. for (pi=getParams();pi!=NULL;pi=pi->next)
  4603. {
  4604. char* xsd = makeXsdType(pi->getMetaString("format_as",NULL));
  4605. pi->write_esp_attr_method(name_, false, getMetaInt("nil_remove")!=0, isDecl, isPure, getMetaInt("trim")!=0,xsd);
  4606. if (xsd)
  4607. free(xsd);
  4608. }
  4609. }
  4610. if (axstype!=espaxm_getters)
  4611. {
  4612. for (pi=getParams();pi!=NULL;pi=pi->next)
  4613. {
  4614. char* xsd = makeXsdType(pi->getMetaString("format_as",NULL));
  4615. pi->write_esp_attr_method(name_, true, getMetaInt("nil_remove")!=0, isDecl, isPure, getMetaInt("trim")!=0,xsd);
  4616. if (xsd)
  4617. free(xsd);
  4618. }
  4619. }
  4620. }
  4621. void EspMessageInfo::write_esp_parms(bool isClientImpl)
  4622. {
  4623. ParamInfo *pi=getParams();
  4624. if (pi)
  4625. {
  4626. if (isClientImpl)
  4627. pi->write_esp_client_impl();
  4628. else
  4629. pi->write_esp_param();
  4630. for (pi=pi->next;pi!=NULL;pi=pi->next)
  4631. {
  4632. if (isClientImpl)
  4633. pi->write_esp_client_impl();
  4634. else
  4635. {
  4636. outs(", ");
  4637. pi->write_esp_param();
  4638. }
  4639. }
  4640. }
  4641. }
  4642. void EspMessageInfo::write_esp_client_method(const char *serv, const char *respname, const char *methname, bool isDecl, bool isPure)
  4643. {
  4644. outs("\n");
  4645. if (isDecl)
  4646. outs("\tvirtual ");
  4647. outf("IClient%s *", respname);
  4648. if (!isDecl && !isPure)
  4649. outf("CClient%s::", serv);
  4650. outf("%sFn(", methname);
  4651. write_esp_parms(false);
  4652. outs(")");
  4653. if (isPure)
  4654. outs("=0");
  4655. if (isDecl)
  4656. outs(";\n");
  4657. else
  4658. {
  4659. outs("\n{\n");
  4660. outf("\tOwned<IClient%s> req = create%sRequest();\n", name_, methname);
  4661. write_esp_parms(true);
  4662. outf("\treturn %s(req.get());\n", methname);
  4663. outs("}\n");
  4664. }
  4665. }
  4666. void EspMessageInfo::write_cpp_interfaces()
  4667. {
  4668. if (espm_type_ == espm_enum)
  4669. {
  4670. // C enum type
  4671. outf("enum C%s { %s_Undefined=-1,", name_, name_);
  4672. const char* base = getParentName();
  4673. bool isIntBase = strieq(base,"int") || strieq(base,"long") || strieq(base,"uint") || strieq(base,"short");
  4674. for (ParamInfo* pi=getParams();pi!=NULL;pi=pi->next)
  4675. {
  4676. outf("C%s_%s", name_, pi->name);
  4677. if (isIntBase) {
  4678. int v = pi->getMetaInt("enum",-1);
  4679. if (v==-1)
  4680. outf("*** invalid value of Enum type");
  4681. outf("=%d",v);
  4682. }
  4683. outs(", ");
  4684. }
  4685. outs("};\n");
  4686. // array of values
  4687. outf("typedef ArrayOf<C%s> %sArray;\n", name_, name_);
  4688. return;
  4689. }
  4690. outf("interface IConst%s : extends ", name_);
  4691. switch (espm_type_)
  4692. {
  4693. case espm_request:
  4694. outs("IEspRequest\n{\n");
  4695. break;
  4696. case espm_response:
  4697. outs("IEspResponse\n{\n");
  4698. break;
  4699. case espm_struct:
  4700. outs("IEspStruct\n{\n");
  4701. break;
  4702. case espm_enum:
  4703. case espm_none:
  4704. assert(!"Code shouldn't be reached");
  4705. break;
  4706. }
  4707. write_esp_methods(espaxm_getters, true, true);
  4708. if (getMetaInt("element")!=0)
  4709. outs(1, "virtual const char * get_tag_value()=0;\n");
  4710. outs("};\n\n");
  4711. outf("interface IEsp%s : extends IConst%s\n{\n", name_, name_);
  4712. write_esp_methods(espaxm_setters, true, true);
  4713. outf("\tvirtual void copy(IConst%s &from)=0;\n", name_);
  4714. if (getMetaInt("element"))
  4715. outs(1, "virtual void set_tag_value(const char *value)=0;\n");
  4716. outs("};\n\n");
  4717. outf("interface IClient%s : extends IInterface\n", name_);
  4718. outs("{\n");
  4719. switch (espm_type_)
  4720. {
  4721. case espm_request:
  4722. outs("\n\tvirtual IEspClientRpcSettings &rpc() = 0;\n\n");
  4723. write_esp_methods(espaxm_setters, true, true);
  4724. write_esp_mapinfo(true);
  4725. break;
  4726. case espm_response:
  4727. outs("\n\tvirtual int queryClientStatus()=0;\n");
  4728. write_esp_methods(espaxm_getters, true, true);
  4729. if (getMetaInt("exceptions_inline")!=0)
  4730. outs("\n\tvirtual const IMultiException& getExceptions()=0;\n");
  4731. write_esp_mapinfo(true);
  4732. break;
  4733. case espm_struct:
  4734. write_esp_methods(espaxm_setters, true, true);
  4735. write_esp_methods(espaxm_getters, true, true);
  4736. break;
  4737. case espm_enum:
  4738. case espm_none:
  4739. assert(!"Code shouldn't be reached");
  4740. break;
  4741. }
  4742. outs("};\n\n");
  4743. }
  4744. void EspMessageInfo::write_factory_decl()
  4745. {
  4746. switch (espm_type_)
  4747. {
  4748. case espm_struct:
  4749. outf("extern \"C\" %s IEsp%s *create%s(const char *serv=NULL, const char *msgname=NULL);\n", (esp_def_export_tag) ? esp_def_export_tag : "", name_, name_);
  4750. outf("extern \"C\" %s IClient%s *createClient%s(const char *serv=NULL, const char *msgname=NULL);\n", (esp_def_export_tag) ? esp_def_export_tag : "", name_, name_);
  4751. break;
  4752. case espm_request:
  4753. case espm_response:
  4754. outf("extern \"C\" %s IEsp%s *create%s(const char *serv=NULL);\n", (esp_def_export_tag) ? esp_def_export_tag : "", name_, name_);
  4755. outf("extern \"C\" %s IClient%s *createClient%s(const char *serv=NULL);\n", (esp_def_export_tag) ? esp_def_export_tag : "", name_, name_);
  4756. break;
  4757. case espm_enum:
  4758. // no factory for enum
  4759. return;
  4760. default:
  4761. assert(!"Unhandled espm type");
  4762. }
  4763. }
  4764. void EspMessageInfo::write_factory_impl()
  4765. {
  4766. switch (espm_type_)
  4767. {
  4768. case espm_struct:
  4769. outf("extern \"C\" %s IEsp%s *create%s(const char *serv, const char *msgname){return ((IEsp%s *)new C%s(serv /*, msgname*/));}\n", (esp_def_export_tag) ? esp_def_export_tag : "", name_, name_, name_, name_);
  4770. outf("extern \"C\" %s IClient%s *createClient%s(const char *serv, const char *msgname){return ((IClient%s *)new C%s(serv /*, msgname*/));}\n", (esp_def_export_tag) ? esp_def_export_tag : "", name_, name_, name_, name_);
  4771. break;
  4772. case espm_request:
  4773. case espm_response:
  4774. outf("extern \"C\" %s IEsp%s *create%s(const char *serv){return ((IEsp%s *)new C%s(serv));}\n", (esp_def_export_tag) ? esp_def_export_tag : "", name_, name_, name_, name_);
  4775. outf("extern \"C\" %s IClient%s *createClient%s(const char *serv){return ((IClient%s *)new C%s(serv));}\n", (esp_def_export_tag) ? esp_def_export_tag : "", name_, name_, name_, name_);
  4776. break;
  4777. case espm_enum:
  4778. break;
  4779. default:
  4780. assert(!"Unhandled espm type");
  4781. }
  4782. }
  4783. void EspMessageInfo::write_clarion_include_interface()
  4784. {
  4785. static char ifname[256];
  4786. strcpy(ifname, "cppClient");
  4787. strcat(ifname, name_);
  4788. outf("%s INTERFACE(cppInterface),COM\n", ifname);
  4789. if (espm_type_==espm_struct)
  4790. {
  4791. write_clarion_methods(espaxm_setters);
  4792. write_clarion_methods(espaxm_getters);
  4793. }
  4794. else if (espm_type_==espm_request)
  4795. write_clarion_methods(espaxm_setters);
  4796. else
  4797. write_clarion_methods(espaxm_getters);
  4798. outs(" END\n\n");
  4799. }
  4800. EspMessageInfo *EspMethodInfo::getRequestInfo()
  4801. {
  4802. EspMessageInfo *msg = hcp->msgs;
  4803. for(;msg!=NULL; msg=msg->next)
  4804. {
  4805. if (!strcmp(msg->getName(), request_))
  4806. return msg;
  4807. }
  4808. return NULL;
  4809. }
  4810. bool EspMethodInfo::write_mapinfo_check(const char* ctxvar)
  4811. {
  4812. StrBuffer minVer, maxVer;
  4813. bool hasMin = getMetaVerInfo("min_ver", minVer);
  4814. bool hasMax = getMetaVerInfo("max_ver", maxVer);
  4815. bool hasOutput = false;
  4816. if (hasMin || hasMax)
  4817. {
  4818. hasOutput = true;
  4819. indentOuts("if (");
  4820. if (hasMin && hasMax)
  4821. outf("(%s.getClientVersion()>=%s && %s.getClientVersion()<=%s)", ctxvar, minVer.str(), ctxvar, maxVer.str());
  4822. else if (hasMin)
  4823. outf("%s.getClientVersion()>=%s", ctxvar,minVer.str());
  4824. else
  4825. outf("%s.getClientVersion()<=%s", ctxvar,maxVer.str());
  4826. }
  4827. const char* optional = getMetaString("optional", NULL);
  4828. if (optional)
  4829. {
  4830. if (hasOutput)
  4831. outs(" && ");
  4832. else
  4833. {
  4834. indentOuts("if (");
  4835. hasOutput = true;
  4836. }
  4837. const char* quote = (*optional == '"') ? "":"\"";
  4838. outf("%s.checkOptional(%s%s%s)", ctxvar, quote,optional,quote);
  4839. }
  4840. if (hasOutput)
  4841. {
  4842. outs(") {\n");
  4843. indentInc(1);
  4844. }
  4845. return hasOutput;
  4846. }
  4847. void EspMethodInfo::write_esp_method(const char *serv, bool isDecl, bool isPure)
  4848. {
  4849. EspMessageInfo *req = getRequestInfo();
  4850. if (req)
  4851. {
  4852. req->write_esp_client_method(serv, getResp(), name_, isDecl, isPure);
  4853. }
  4854. }
  4855. void EspServInfo::write_factory_impl()
  4856. {
  4857. outs("extern \"C\"");
  4858. if (esp_def_export_tag)
  4859. outf(" %s", esp_def_export_tag);
  4860. outf(" IClient%s * create%sClient() { return new CClient%s(); }\n", name_, name_, name_);
  4861. }
  4862. using HidlAccessMapGenerator = TAccessMapGenerator<const char*>;
  4863. using HidlAccessMapScopeMapper = HidlAccessMapGenerator::ScopeMapper;
  4864. struct HidlAccessMapLevelMapper : public HidlAccessMapGenerator::LevelMapper
  4865. {
  4866. const char* levelUnavailable() const override { return "SecAccess_Unavailable"; }
  4867. const char* levelNone() const override { return "SecAccess_None"; }
  4868. const char* levelDeferred() const override { return "SecAccess_None"; }
  4869. const char* levelAccess() const override { return "SecAccess_Access"; }
  4870. const char* levelRead() const override { return "SecAccess_Read"; }
  4871. const char* levelWrite() const override { return "SecAccess_Write"; }
  4872. const char* levelFull() const override { return "SecAccess_Full"; }
  4873. const char* levelUnknown() const override { return "SecAccess_Unknown"; }
  4874. bool isEqual(const char* lhs, const char* rhs) const override
  4875. {
  4876. return (lhs != nullptr && rhs != nullptr && strieq(lhs, rhs));
  4877. }
  4878. const char* toString(const char* level) const override
  4879. {
  4880. return level;
  4881. }
  4882. };
  4883. struct HidlAccessMapReporter : public HidlAccessMapGenerator::Reporter
  4884. {
  4885. StrBuffer indent;
  4886. HidlAccessMapReporter(int tabs)
  4887. {
  4888. for (int tabindex = 0; tabindex < tabs; tabindex++)
  4889. indent.append('\t');
  4890. }
  4891. bool reportInfo() const override { return false; }
  4892. bool reportDebug() const override { return false; }
  4893. void preEntry(size_t termCount) const override
  4894. {
  4895. outf("%sMapStringTo<SecAccessFlags> accessmap;\n", indent.str());
  4896. }
  4897. void entry(const char* name, const char* level) const override
  4898. {
  4899. outf("%saccessmap.setValue(\"%s\", %s);\n", indent.str(), name, level);
  4900. }
  4901. protected:
  4902. void reportError(const char* fmt, va_list& args) const override
  4903. {
  4904. reportSomething("\nERROR: ", fmt, args);
  4905. }
  4906. void reportWarning(const char* fmt, va_list& args) const override
  4907. {
  4908. reportSomething("//WARNING: ", fmt, args);
  4909. }
  4910. void reportInfo(const char* fmt, va_list& args) const override
  4911. {
  4912. reportSomething("//INFO: ", fmt, args);
  4913. }
  4914. void reportDebug(const char* fmt, va_list& args) const override
  4915. {
  4916. reportSomething("//DEBUG: ", fmt, args);
  4917. }
  4918. inline void reportSomething(const char* prefix, const char* fmt, va_list& args) const
  4919. {
  4920. outs(prefix);
  4921. voutf(fmt, args);
  4922. outs("\n");
  4923. }
  4924. };
  4925. void writeAccessMap(int indentLevel, EspServInfo& svci, const char* serviceName, const char* serviceFragment, EspMethodInfo& mthi)
  4926. {
  4927. HidlAccessMapScopeMapper scopeMapper({"EsdlService", "EsdlMethod"});
  4928. HidlAccessMapLevelMapper levelMapper;
  4929. HidlAccessMapReporter reporter(indentLevel);
  4930. HidlAccessMapGenerator generator(scopeMapper, levelMapper, reporter);
  4931. generator.setVariable("service", serviceName);
  4932. generator.setVariable("method", mthi.getName());
  4933. generator.insertScope("EsdlService", serviceFragment);
  4934. generator.insertScope("EsdlMethod", mthi.getMetaString(FEATEACCESSATTRIBUTE, NULL));
  4935. generator.setDefaultSecurity("${service}Access:FULL");
  4936. generator.generateMap();
  4937. }
  4938. void EspServInfo::write_esp_binding_ipp()
  4939. {
  4940. EspMethodInfo *mthi=NULL;
  4941. int useMethodName = getMetaInt("use_method_name", 0);
  4942. outf("\n\nclass C%sSoapBinding : public CHttpSoapBinding\n", name_);
  4943. outs("{\npublic:\n");
  4944. //dom
  4945. outf("\tC%sSoapBinding(http_soap_log_level level=hsl_none);\n", name_);
  4946. outf("\tC%sSoapBinding(IPropertyTree* cfg, const char *bindname=NULL, const char *procname=NULL, http_soap_log_level level=hsl_none);\n", name_);
  4947. outs("\tvirtual void init_strings();\n");
  4948. outs("\tvirtual unsigned getCacheMethodCount(){return m_cacheMethodCount;}\n");
  4949. //method ==> processRequest
  4950. outs("\tvirtual int processRequest(IRpcMessage* rpc_call, IRpcMessage* rpc_response);\n");
  4951. //method ==> getXsdDefinition
  4952. outs("\tint getXsdDefinition(IEspContext &context, CHttpRequest* request, StringBuffer &content, const char *service, const char *method, bool mda);\n");
  4953. //method ==> getMethodHtmlForm
  4954. outs("\tvirtual int getMethodHtmlForm(IEspContext &context, CHttpRequest* request, const char *serv, const char *method, StringBuffer &page, bool bIncludeFormTag);\n");
  4955. //method ==> getQualifiedNames
  4956. outs("\tint getQualifiedNames(IEspContext& ctx, MethodInfoArray & methods);\n");
  4957. //method ==> getServiceName
  4958. outs("\tStringBuffer & getServiceName(StringBuffer &resp);\n");
  4959. //method ==> isValidServiceName
  4960. outs("\tbool isValidServiceName(IEspContext &context, const char *name);\n");
  4961. //method ==> qualifyMethodName
  4962. outs("\tbool qualifyMethodName(IEspContext &context, const char *methname, StringBuffer *methQName);\n");
  4963. //method ==> qualifyServiceName
  4964. outs("\tbool qualifyServiceName(IEspContext &context, const char *servname, const char *methname, StringBuffer &servQName, StringBuffer *methQName);\n");
  4965. //method ==> onGetFile
  4966. outs("\tvirtual int onGetFile(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *pathex);\n");
  4967. //Method ==> onGetForm
  4968. outs("\tvirtual int onGetForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method);\n");
  4969. //Method ==> onGetXForm
  4970. //if (getMetaInt("use_new_form",0))
  4971. outs("\tvirtual int onGetXForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method);\n");
  4972. //Method ==> supportGeneratedForms
  4973. if (getMetaInt("noforms", 0))
  4974. outs("\tvirtual bool supportGeneratedForms(){return false;}\n");
  4975. if (getMetaInt("no_ws_index", 0))
  4976. {
  4977. //Method ==> onGetIndex
  4978. outs("\tvirtual int onGetIndex(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service)\n");
  4979. outs("\t{\n");
  4980. outs("\t\treturn onGetNotFound(context, request, response, service);\n");
  4981. outs("\t}\n");
  4982. }
  4983. //Method ==> onGetService
  4984. outs("\tvirtual int onGetService(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method, const char *pathex);\n");
  4985. //Method ==> createReqBinding
  4986. outs(1, "virtual IRpcRequestBinding *createReqBinding(IEspContext &context, IHttpMessage* request, const char *service, const char *method);\n");
  4987. //Method ==> onGetInstantQuery
  4988. outs("\tvirtual int onGetInstantQuery(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method);\n");
  4989. //Method ==> xslTransform
  4990. if (needsXslt)
  4991. {
  4992. outs(1, "void setXslProcessor(IInterface *xslp_)\n");
  4993. outs(1, "{\n");
  4994. outs(2, "IXslProcessor *ixslp = dynamic_cast<IXslProcessor *>(xslp_);\n");
  4995. outs(2, "if (!ixslp)\n");
  4996. outs(3, "xslp.clear();\n"); //set(NULL) would basically be same, but be explicit
  4997. outs(2, "else\n");
  4998. outs(3, "xslp.set(ixslp);\n");
  4999. outs(1, "}\n");
  5000. outs("private:\n");
  5001. outs("\tOwned<IXslProcessor> xslp;\n");
  5002. outs("\tvoid xslTransform(const char* xml, const char* xslFile, StringBuffer& output, IProperties *params)\n"
  5003. "\t{\n"
  5004. "\t\tif (xslp)\n"
  5005. "\t\t{\n"
  5006. "\t\t\tOwned<IXslTransform> xform = xslp->createXslTransform();\n"
  5007. "\t\t\tStringBuffer xslpath;\n"
  5008. "\t\t\tif (!strnicmp(xslFile, \"/esp/xslt/\", 10))\n"
  5009. "\t\t\t\tif (!checkFileExists(xslpath.append(getCFD()).append(\"smc_xslt/\").append(xslFile+10).str()) && !checkFileExists(xslpath.append(getCFD()).append(\"xslt/\").append(xslFile+10).str()))\n"
  5010. "\t\t\t\t\treturn;\n"
  5011. "\t\t\txform->loadXslFromFile((xslpath.length()) ? xslpath.str() : xslFile);\n"
  5012. "\t\t\txform->setXmlSource(xml, strlen(xml)+1);\n"
  5013. "\t\t\tif (params) xform->copyParameters(params);\n"
  5014. "\t\t\txform->transform(output.clear());\n"
  5015. "\t\t}\n"
  5016. "\t}\n");
  5017. }
  5018. else
  5019. outs("\tvoid setXslProcessor(IInterface *xslp){}\n");
  5020. outs("\tunsigned m_cacheMethodCount = 0;\n");
  5021. outs("};\n\n");
  5022. }
  5023. void EspServInfo::write_esp_binding()
  5024. {
  5025. EspMethodInfo *mthi=NULL;
  5026. int useMethodName = getMetaInt("use_method_name", 0);
  5027. StrBuffer wsdlVer;
  5028. bool hasVersion = getMetaVerInfo(tags,"version",wsdlVer);
  5029. if (!hasVersion)
  5030. wsdlVer.append("1");
  5031. //comment
  5032. outs("\n//=======================================================");
  5033. outf("\n// class C%sSoapBinding Implementation", name_);
  5034. outs("\n//=======================================================");
  5035. outs("\n");
  5036. StrBuffer servicefeatureurl;
  5037. getMetaStringValue(servicefeatureurl,FEATEACCESSATTRIBUTE);
  5038. outf("\nC%sSoapBinding::C%sSoapBinding(http_soap_log_level level):CHttpSoapBinding(NULL, NULL, NULL, level)\n{\n\tinit_strings();\n\tsetWsdlVersion(%s);", name_, name_, wsdlVer.str());
  5039. outf("\n}\n");
  5040. outf("\nC%sSoapBinding::C%sSoapBinding(IPropertyTree* cfg, const char *bindname, const char *procname, http_soap_log_level level):CHttpSoapBinding(cfg, bindname, procname, level)\n{\n\tinit_strings(); \n\tsetWsdlVersion(%s);\n", name_, name_, wsdlVer.str());
  5041. outf("\n}\n");
  5042. outf("\nvoid C%sSoapBinding::init_strings()\n", name_);
  5043. outs("{\n");
  5044. bool cacheDefined = false;
  5045. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5046. {
  5047. StrBuffer val;
  5048. mthi->getMetaStringValue(val,"description");
  5049. if (val.length()) {
  5050. StrBuffer tmp;
  5051. outf("\taddMethodDescription(\"%s\", \"%s\");\n", mthi->getName(), printfEncode(val.str(), tmp).str());
  5052. }
  5053. mthi->getMetaStringValue(val.clear(),"help");
  5054. if (val.length()) {
  5055. StrBuffer tmp;
  5056. outf("\taddMethodHelp(\"%s\", \"%s\");\n", mthi->getName(), printfEncode(val.str(), tmp).str());
  5057. }
  5058. int cacheGlobal = mthi->getMetaInt("cache_global", 0);
  5059. int cacheSeconds = mthi->getMetaInt("cache_seconds", -1);
  5060. if (cacheSeconds > -1) {
  5061. cacheDefined = true;
  5062. if (cacheGlobal > 0)
  5063. outf("\tsetCacheTimeout(\"%s\", %d, 1);\n", mthi->getName(), cacheSeconds);
  5064. else
  5065. outf("\tsetCacheTimeout(\"%s\", %d, 0);\n", mthi->getName(), cacheSeconds);
  5066. outs("\tm_cacheMethodCount++;\n");
  5067. StrBuffer methodCacheGroupID;
  5068. mthi->getMetaStringValue(methodCacheGroupID,"cache_group");
  5069. if (methodCacheGroupID.length() > 0)
  5070. outf("\tsetCacheGroupID(\"%s\", \"%s\");\n", mthi->getName(), methodCacheGroupID.str());
  5071. }
  5072. }
  5073. StrBuffer serviceCacheGroupID;
  5074. if (cacheDefined)
  5075. {
  5076. getMetaStringValue(serviceCacheGroupID,"cache_group");
  5077. if (serviceCacheGroupID.length() == 0)
  5078. serviceCacheGroupID.set(name_);
  5079. outf("\tsetCacheGroupID(nullptr, \"%s\");\n", serviceCacheGroupID.str());
  5080. }
  5081. outs("}\n");
  5082. outf("\nint C%sSoapBinding::processRequest(IRpcMessage* rpc_call, IRpcMessage* rpc_response)\n", name_);
  5083. outs("{\n");
  5084. outs("\tif(rpc_call == NULL || rpc_response == NULL)\n\t\treturn -1;\n\n");
  5085. outs(1, "IEspContext *ctx=rpc_call->queryContext();\n");
  5086. outs(1, "DBGLOG(\"Client version: %g\", ctx->getClientVersion());\n");
  5087. outs(1, "StringBuffer serviceName;\n");
  5088. outs(1, "double clientVer=(ctx) ? ctx->getClientVersion() : 0.0;\n");
  5089. outs(1, "qualifyServiceName(*ctx, ctx->queryServiceName(NULL), NULL, serviceName, NULL);\n");
  5090. outs(1, "CRpcCall* thecall = static_cast<CRpcCall *>(rpc_call);\n"); //interface must be from a class derived from CRpcCall
  5091. outs(1, "CRpcResponse* response = static_cast<CRpcResponse*>(rpc_response);\n"); //interface must be from a class derived from CRpcResponse
  5092. outs(1, "CHttpRequest* httprequest = thecall->getHttpReq();\n");
  5093. outs(1, "CHttpResponse* httpresponse = response->getHttpResp();\n\n");
  5094. outf("\tOwned<IEsp%s> iserv = (IEsp%s*)getService();\n", name_, name_);
  5095. outs("\tif(iserv == NULL)\n");
  5096. outs("\t{\n");
  5097. outs("\t\tresponse->set_status(SOAP_SERVER_ERROR);\n");
  5098. outs("\t\tresponse->set_err(\"Service not available\");\n");
  5099. outs("\t\tDBGLOG(\"Service not available\");\n");
  5100. outs("\t\treturn -1;\n\t}\n");
  5101. outs("\tif (thecall->get_name() == NULL)\n");
  5102. outs("\t{\n");
  5103. outs("\t\tresponse->set_status(SOAP_CLIENT_ERROR);\n");
  5104. outs("\t\tresponse->set_err(\"No service method specified\");\n");
  5105. outs("\t\tERRLOG(\"No service method specified\");\n");
  5106. outs("\t\treturn -1;\n");
  5107. outs("\t}\n");
  5108. outs("\n\tIEspContext& context = *rpc_call->queryContext();\n\n");
  5109. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5110. {
  5111. outf("\tif(!stricmp(thecall->get_name(), \"%s\")||!stricmp(thecall->get_name(), \"%s\"))\n", mthi->getName(), mthi->getReq());
  5112. outs("\t{\n");
  5113. //esp_request + esp_response can persist longer than the scope of this method
  5114. outf("\t\tOwned<C%s> esp_request = new C%s(serviceName.str(), thecall);\n", mthi->getReq(), mthi->getReq());
  5115. outs("\t\tcheckRequest(context);\n");
  5116. outf("\t\tOwned<C%s> esp_response = new C%s(serviceName.str());\n", mthi->getResp(), mthi->getResp());
  5117. StrBuffer minVer;
  5118. bool hasMinVer = mthi->getMetaVerInfo("min_ver", minVer);
  5119. if (hasMinVer) {
  5120. outs(2, "if (!clientVer) {\n");
  5121. outf(3, "clientVer = %s;\n", minVer.str());
  5122. outs(3, "ctx->setClientVersion(clientVer);\n");
  5123. outs(2, "}\n");
  5124. }
  5125. bool bHandleExceptions = 0 != mthi->getMetaInt("exceptions_inline", 0);
  5126. if (!bHandleExceptions)
  5127. bHandleExceptions = 0 != getMetaInt("exceptions_inline", 0);
  5128. writeAccessMap(2, *this, name_, servicefeatureurl, *mthi);
  5129. StrBuffer clearCacheGroupIDs;
  5130. if (mthi->hasMetaTag("clear_cache_group"))
  5131. {
  5132. StrBuffer cCGIDs;
  5133. mthi->getMetaStringValue(cCGIDs,"clear_cache_group");
  5134. if (cacheDefined || (cCGIDs.length() != 0))
  5135. clearCacheGroupIDs.set((cCGIDs.length() != 0) ? cCGIDs.str() : serviceCacheGroupID.str());
  5136. }
  5137. //begin try block
  5138. if (bHandleExceptions)
  5139. {
  5140. outs("\t\tStringBuffer source;\n");
  5141. outf("\t\tsource.appendf(\"%s::%%s()\", thecall->get_name());\n", name_);
  5142. outf("\t\tOwned<IMultiException> me = MakeMultiException(source.str());\n");
  5143. outs("\t\ttry\n");
  5144. outs("\t\t{\n");
  5145. if (hasMinVer)
  5146. {
  5147. outf("\t\t\tif (clientVer!=-1.0 && clientVer<%s)\n", minVer.str());
  5148. outs("\t\t\t\tthrow MakeStringException(-1, \"Client version is too old, please update your client application.\");");
  5149. }
  5150. outs("\t\t\tresponse->set_status(SOAP_OK);\n");
  5151. if (servicefeatureurl.length() != 0)
  5152. outf("\t\t\tif( accessmap.ordinality() > 0 )\n\t\t\t\tonFeaturesAuthorize(context, accessmap, \"%s\", \"%s\");\n", name_, mthi->getName());
  5153. outf("\t\t\tiserv->on%s(context, *esp_request, *esp_response);\n", mthi->getName());
  5154. if (clearCacheGroupIDs.length() > 0)
  5155. outf("\t\t\tclearCacheByGroupID(\"%s\");\n", clearCacheGroupIDs.str());
  5156. outs("\t\t}\n");
  5157. write_catch_blocks(mthi, ct_soapresp, 2);
  5158. }
  5159. else
  5160. {
  5161. if (hasMinVer)
  5162. {
  5163. outf(2, "if (clientVer!=-1.0 && clientVer<%s)\n", minVer.str());
  5164. outf(3, "throw MakeStringException(-1, \"This method is not supported in version %%g, minimum version is %s. Please update your client application.\", clientVer);\n", minVer.str());
  5165. }
  5166. if (mthi->getMetaInt("do_not_log",0))
  5167. outs(2, "context.queryRequestParameters()->setProp(\"do_not_log\",1);\n");
  5168. if (servicefeatureurl.length() != 0) {
  5169. outs(2, "if( accessmap.ordinality() > 0 )\n");
  5170. outf(3, "onFeaturesAuthorize(context, accessmap, \"%s\", \"%s\");\n", name_, mthi->getName());
  5171. }
  5172. outf(2, "iserv->on%s(*rpc_call->queryContext(), *esp_request, *esp_response);\n", mthi->getName());
  5173. if (clearCacheGroupIDs.length() > 0)
  5174. outf(2, "clearCacheByGroupID(\"%s\");\n", clearCacheGroupIDs.str());
  5175. outs(2, "response->set_status(SOAP_OK);\n");
  5176. }
  5177. outf("\t\tresponse->set_name(\"%s\");\n", mthi->getResp());
  5178. outs("\t\tif(!httprequest || !httpresponse)\n");
  5179. outs("\t\t{\n");
  5180. outs("\t\t\tesp_response->serialize(*response);\n");
  5181. outs("\t\t}\n");
  5182. outs("\t\telse\n");
  5183. outs("\t\t{\n");
  5184. outs("\t\t\tMemoryBuffer content;\n");
  5185. outs("\t\t\tStringBuffer mimetype;\n");
  5186. outs("\t\t\tesp_response->appendContent(&context,content, mimetype);\n");
  5187. outs("\t\t\tonBeforeSendResponse(context,httprequest,content,serviceName.str(),thecall->get_name());\n");
  5188. outs("\t\t\thttpresponse->setContent(content.length(), content.toByteArray());\n");
  5189. outs("\t\t\thttpresponse->setContentType(mimetype.str());\n");
  5190. outs("\t\t\thttpresponse->send();\n");
  5191. outs("\t\t\thttpresponse->setRespSent(true);\n");
  5192. outs("\t\t}\n");
  5193. outs("\t\treturn 0;\n\t}\n\n");
  5194. }
  5195. outs("\tresponse->set_status(SOAP_CLIENT_ERROR);\n");
  5196. outs("\tStringBuffer msg, svcName;\n");
  5197. outs("\tmsg.appendf(\"Method %s not available in service %s\",thecall->get_name(),getServiceName(svcName).str());\n");
  5198. outs("\tERRLOG(\"%s\", msg.str());\n");
  5199. outs("\tresponse->set_err(msg);\n");
  5200. outs("\treturn -1;\n");
  5201. outs("}\n");
  5202. //method ==> getXsdDefinition
  5203. outf("\nint C%sSoapBinding::getXsdDefinition(IEspContext &context, CHttpRequest* request, StringBuffer &content, const char *service, const char *method, bool mda)\n", name_);
  5204. outs("{\n");
  5205. outs("\tBoolHash added;\n");
  5206. // version
  5207. if (hasVersion)
  5208. {
  5209. outs("\tif (context.getClientVersion()<=0)\n");
  5210. outf("\t\tcontext.setClientVersion(%s);\n\n", wsdlVer.str());
  5211. }
  5212. outs("\tDBGLOG(\"Client version: %g\", context.getClientVersion());\n");
  5213. indentReset(1);
  5214. outf(1, "bool fullservice = (!Utils::strcasecmp(service, \"%s\"));\n", name_);
  5215. indentOuts("bool allMethods = (method==NULL || *method==0);\n");
  5216. bool needPropsDeclare = true;
  5217. bool needAccessFlagDeclare = true;
  5218. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5219. {
  5220. const char *requestName = (useMethodName) ? mthi->getName() : mthi->getReq();
  5221. const char *optional=mthi->getMetaString("optional", NULL);
  5222. const char *access=mthi->getMetaString("access", NULL);
  5223. if (optional)
  5224. {
  5225. if (needPropsDeclare)
  5226. {
  5227. indentOuts("IProperties *props = request->queryParameters();\n");
  5228. needPropsDeclare = false;
  5229. }
  5230. indentOutf("if (props && props->hasProp(%s)) {\n", optional);
  5231. indentInc(1);
  5232. }
  5233. if (access)
  5234. {
  5235. if (needAccessFlagDeclare)
  5236. {
  5237. indentOuts("SecAccessFlags acc;\n");
  5238. needAccessFlagDeclare = false;
  5239. }
  5240. indentOutf("if (context.authorizeFeature(%s, acc) && acc>=SecAccess_Read) {\n", access);
  5241. indentInc(1);
  5242. }
  5243. indentOutf("if ((allMethods&&(fullservice||isMethodInSubService(context, service, \"%s\"))) || Utils::strcasecmp(method, \"%s\")==0)\n", mthi->getName(), mthi->getName());
  5244. indentOuts("{\n");
  5245. indentInc(1);
  5246. bool hasMap = mthi->write_mapinfo_check("context");
  5247. indentOutf("C%s::getMapInfo(context.queryMapInfo());\n", mthi->getReq());
  5248. indentOutf("C%s::getMapInfo(context.queryMapInfo());\n", mthi->getResp());
  5249. indentOutf("C%s::getXsdDefinition(context, request, \"%s\", content, added);\n", mthi->getReq(), requestName);
  5250. indentOutf("C%s::getXsdDefinition(context, request, content, added);\n", mthi->getResp());
  5251. if (hasMap)
  5252. indentOuts(-1,"}\n");
  5253. indentOuts(-1,"}\n");
  5254. if (access)
  5255. indentOuts(-1,"}\n");
  5256. if (optional)
  5257. indentOuts(-1,"}\n");
  5258. }
  5259. indentOuts("return 0;\n");
  5260. indentOuts(-1,"}\n");
  5261. //method ==> getMethodHtmlForm
  5262. outf("\nint C%sSoapBinding::getMethodHtmlForm(IEspContext &context, CHttpRequest* request, const char *serv, const char *method, StringBuffer &page, bool bIncludeFormTag)\n", name_);
  5263. outs("{\n");
  5264. outf("\tDBGLOG(\"Client version: %%g\", context.getClientVersion());\n");
  5265. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5266. {
  5267. outf("\tif (Utils::strcasecmp(method, \"%s\")==0)\n", mthi->getName());
  5268. outs("\t{\n");
  5269. outf("\t\tC%s::getHtmlForm(context, request, serv, method, page);\n", mthi->getReq());
  5270. outs("\t}\n");
  5271. }
  5272. outs("\treturn 0;\n");
  5273. outs("}\n");
  5274. //method ==> getQualifiedNames
  5275. outf("\nint C%sSoapBinding::getQualifiedNames(IEspContext& ctx, MethodInfoArray & methods)\n", name_);
  5276. outs("{\n");
  5277. outs(1, "double ver = ctx.getClientVersion();\n");
  5278. outs(1, "if (ver<=0)\n");
  5279. outs(2, "ver = getWsdlVersion();\n");
  5280. outs(1, "const char *servname=ctx.queryServiceName(NULL);\n");
  5281. outf(1, "bool fullservice = (!stricmp(servname, \"esp\")||!stricmp(servname, \"%s\"));\n", name_);
  5282. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5283. {
  5284. if (!mthi->getMetaInt("noform",0))
  5285. {
  5286. const char *optional=mthi->getMetaString("optional", "NULL");
  5287. const char *access=mthi->getMetaString("access", "NULL");
  5288. const char *method_name = (getMetaInt("use_method_name")!=0) ? mthi->getName() : mthi->getReq();
  5289. StrBuffer minVer, maxVer;
  5290. bool hasMinVer = mthi->getMetaVerInfo("min_ver",minVer);
  5291. bool hasMaxVer = mthi->getMetaVerInfo("max_ver",maxVer);
  5292. outf("\tif ((fullservice || isMethodInSubService(ctx, servname, \"%s\")) && ctx.isMethodAllowed(ver,%s, %s, %s, %s))\n",
  5293. mthi->getName(), optional, access, hasMinVer ? minVer.str() : "-1", hasMaxVer ? maxVer.str() : "-1");
  5294. outf("\t\tmethods.append(*new CMethodInfo(\"%s\", \"%s\", \"%s\"));\n", mthi->getName(), method_name, mthi->getResp());
  5295. }
  5296. }
  5297. outs("\treturn methods.ordinality();\n");
  5298. outs("}\n");
  5299. //method ==> getServiceName
  5300. outf("\nStringBuffer & C%sSoapBinding::getServiceName(StringBuffer &resp)\n", name_);
  5301. outs("{\n");
  5302. outf("\tresp.append(\"%s\");\n", name_);
  5303. outs("\treturn resp;\n");
  5304. outs("}\n");
  5305. //method ==> isValidServiceName
  5306. outf("\nbool C%sSoapBinding::isValidServiceName(IEspContext &context, const char *name)\n", name_);
  5307. outs("{\n");
  5308. outf(1, "if (!Utils::strcasecmp(name, \"%s\"))\n", name_);
  5309. outs(2, "return true;\n");
  5310. outs(1, "else\n");
  5311. outs(2, "return (hasSubService(context, name));\n");
  5312. outs("}\n");
  5313. //method ==> qualifyMethodName
  5314. outf("\nbool C%sSoapBinding::qualifyMethodName(IEspContext &context, const char *methname, StringBuffer *methQName)\n", name_);
  5315. outs("{\n");
  5316. outs("\tif (!methname || !*methname)\n");
  5317. outs("\t{\n");
  5318. outs("\t\tif (methQName!=NULL)\n");
  5319. outs("\t\t\tmethQName->clear();\n");
  5320. outs("\t\treturn true;\n");
  5321. outs("\t}\n");
  5322. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5323. {
  5324. outf("\tif (Utils::strcasecmp(methname, \"%s\")==0)\n", mthi->getName());
  5325. outs("\t{\n");
  5326. outs("\t\tif (methQName!=NULL)\n");
  5327. outf("\t\t\tmethQName->set(\"%s\");\n", mthi->getName());
  5328. outs("\t\treturn true;\n");
  5329. outs("\t}\n");
  5330. }
  5331. outs("\treturn false;\n");
  5332. outs("}\n");
  5333. //method ==> qualifyServiceName
  5334. outf("\nbool C%sSoapBinding::qualifyServiceName(IEspContext &context, const char *servname, const char *methname, StringBuffer &servQName, StringBuffer *methQName)\n", name_);
  5335. outs("{\n");
  5336. outs(1, "servQName.clear();\n");
  5337. outf(1, "if (!Utils::strcasecmp(servname, \"%s\"))\n", name_);
  5338. outs(1, "{\n");
  5339. outf(2, "servQName.append(\"%s\");\n", name_);
  5340. outs(2, "return qualifyMethodName(context, methname, methQName);\n");
  5341. outs(1, "}\n");
  5342. outs(1, "return qualifySubServiceName(context, servname, methname, servQName, methQName);\n");
  5343. outs("}\n");
  5344. //method ==> onGetFile
  5345. outf("\nint C%sSoapBinding::onGetFile(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *pathex)\n", name_);
  5346. outs("{\n");
  5347. outs("\tif(request == NULL || response == NULL)\n");
  5348. outs("\t\treturn -1;\n");
  5349. outs("\tStringBuffer mimetype;\n");
  5350. outs("\tMemoryBuffer content;\n\n");
  5351. outs("\tStringBuffer filepath;\n");
  5352. outs("\tgetBaseFilePath(filepath);\n");
  5353. outs("\tif (strchr(\"\\\\/\", filepath.charAt(filepath.length()-1))==NULL)\n");
  5354. outs("\t\tfilepath.append(\"/\");\n");
  5355. outs("\tfilepath.append(pathex);\n");
  5356. outs("\tresponse->httpContentFromFile(filepath.str());\n");
  5357. outs("\tresponse->send();\n");
  5358. outs("\treturn 0;\n");
  5359. outs("}\n");
  5360. //Method ==> onGetForm
  5361. outf("\nint C%sSoapBinding::onGetForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method)\n", name_);
  5362. outs("{\n");
  5363. if (getMetaInt("noforms", 0))
  5364. {
  5365. outs("\treturn onGetNotFound(context, request, response, service);\n");
  5366. }
  5367. else
  5368. {
  5369. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5370. {
  5371. if (mthi->getMetaInt("noform", 0))
  5372. {
  5373. outf("\tif (!stricmp(\"%s\", method))\n", mthi->getName());
  5374. outs("\t\treturn onGetNotFound(context, request, response, service);\n");
  5375. }
  5376. else
  5377. {
  5378. const char *formHtmlPath = mthi->getMetaString("form_html", NULL);
  5379. if (formHtmlPath)
  5380. {
  5381. outf("\tif (!stricmp(\"%s\", method))\n", mthi->getName());
  5382. outs("\t{\n");
  5383. outf("\t\tresponse->httpContentFromFile(%s);\n", formHtmlPath);
  5384. outs("\t\tresponse->send();\n");
  5385. outs("\t\treturn 0;\n");
  5386. outs("\t}\n");
  5387. }
  5388. }
  5389. }
  5390. // normal test form
  5391. if (hasVersion)
  5392. {
  5393. outs("\tif (context.getClientVersion()<=0)\n");
  5394. outf("\t\tcontext.setClientVersion(%s);\n\n", wsdlVer.str());
  5395. }
  5396. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5397. {
  5398. outf("\tif (!stricmp(\"%s\", method)) {\n", mthi->getName());
  5399. if (mthi->getMetaInt("use_new_form",0))
  5400. outs("\t\treturn EspHttpBinding::onGetXForm(context, request, response, service, method);\n");
  5401. else {
  5402. outf("\t\tC%s::getMapInfo(context.queryMapInfo());\n", mthi->getReq());
  5403. outf("\t\tC%s::getMapInfo(context.queryMapInfo());\n", mthi->getResp());
  5404. }
  5405. outs("\t}\n");
  5406. }
  5407. outs("\n\treturn EspHttpBinding::onGetForm(context, request, response, service, method);\n");
  5408. }
  5409. outs("}\n");
  5410. // method ==> onGetXForm
  5411. outf("int C%sSoapBinding::onGetXForm(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method)\n", name_);
  5412. outs("{\n");
  5413. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5414. {
  5415. if (mthi->getMetaInt("use_new_form",0))
  5416. {
  5417. outf("\tif (!stricmp(\"%s\", method))\n", mthi->getName());
  5418. outs("\t\treturn EspHttpBinding::onGetForm(context, request, response, service, method);\n");
  5419. }
  5420. }
  5421. outs("\treturn EspHttpBinding::onGetXForm(context, request, response, service, method);\n");
  5422. outs("}\n");
  5423. if (getMetaInt("no_ws_index", 0))
  5424. {
  5425. //Method ==> onGetIndex
  5426. outf("\nint C%sSoapBinding::onGetIndex(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service)\n", name_);
  5427. outs("{\n");
  5428. outs("\treturn onGetNotFound(context, request, response, service);\n");
  5429. outs("}\n");
  5430. }
  5431. //Method ==> onGetService
  5432. outf("\nint C%sSoapBinding::onGetService(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method, const char *pathex)\n", name_);
  5433. outs("{\n");
  5434. outs("\tif(request == NULL || response == NULL)\n");
  5435. outs("\t\treturn -1;\n");
  5436. EspMountInfo *mnt;
  5437. for (mnt=mounts;mnt!=NULL;mnt=mnt->next)
  5438. {
  5439. outs("\t");
  5440. if (mnt!=mounts)
  5441. outs("else ");
  5442. outf("if(!stricmp(method, \"%s\"))\n", mnt->getName());
  5443. outs("\t{\n");
  5444. outs("\t\tMemoryBuffer content;\n");
  5445. outs("\t\tStringBuffer mimetype;\n");
  5446. outf("\t\tStringBuffer filepath(%s);\n\n", mnt->getLocalPath());
  5447. outs("\t\tif (filepath.length()>0 && strchr(\"/\\\\\", filepath.charAt(filepath.length()-1))==NULL)\n");
  5448. outs("\t\t{\n");
  5449. outs("\t\t\tfilepath.append(\"/\");\n");
  5450. outs("\t\t}\n");
  5451. outs("\t\tfilepath.append((pathex!=NULL && *pathex!=0) ? pathex : \"index.html\");\n\n");
  5452. outs("\t\tif (!response->httpContentFromFile(filepath.str()))\n");
  5453. outs("\t\t{\n");
  5454. outs("\t\t\treturn onGetQuery(context, request, response, service, method);\n");
  5455. outs("\t\t}\n");
  5456. outs("\t\tresponse->send();\n");
  5457. outs("\t\treturn 0;\n");
  5458. outs("\t}\n");
  5459. }
  5460. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5461. {
  5462. int formIsDefault = mthi->getMetaInt("form_is_default");
  5463. if (formIsDefault)
  5464. {
  5465. outf("\tif (!stricmp(\"%s\", method))\n", mthi->getName());
  5466. outs("\t{\n");
  5467. outs("\treturn onGetForm(context, request, response, service, method);\n");
  5468. outs("\t}\n");
  5469. }
  5470. }
  5471. outs("\treturn onGetQuery(context, request, response, service, method);\n");
  5472. outs("}\n");
  5473. outf("\n IRpcRequestBinding *C%sSoapBinding::createReqBinding(IEspContext &context, IHttpMessage *ireq, const char *service, const char *method)\n", name_);
  5474. outs("{\n");
  5475. outs(1, "CHttpRequest *request=static_cast<CHttpRequest*>(ireq);\n");
  5476. outs(1, "IProperties *props = (request) ? request->queryParameters() : NULL;\n\n");
  5477. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5478. {
  5479. outf(1, "if (!stricmp(method, \"%s\") || !stricmp(method, \"%s\"))\n", mthi->getName(), mthi->getReq());
  5480. outf(2, "return new C%s(&context, \"%s\", props, NULL);\n", mthi->getReq(), name_);
  5481. }
  5482. outs(1, "return NULL;\n");
  5483. outs("}\n");
  5484. //Method ==> onGetInstantQuery
  5485. outf("\nint C%sSoapBinding::onGetInstantQuery(IEspContext &context, CHttpRequest* request, CHttpResponse* response, const char *service, const char *method)\n", name_);
  5486. outs("{\n");
  5487. StrBuffer defVer;
  5488. bool hasDefVer = getMetaVerInfo(tags,"default_client_version",defVer);
  5489. if (!hasDefVer)
  5490. hasDefVer = getMetaVerInfo(tags,"version",defVer);
  5491. if (hasDefVer)
  5492. {
  5493. outf("\tif (context.getClientVersion()<=0)\n");
  5494. outf("\t\tcontext.setClientVersion(%s);\n\n", defVer.str());
  5495. }
  5496. outs("\tif(request == NULL || response == NULL)\n");
  5497. outs("\t\treturn -1;\n");
  5498. outs("\tStringBuffer respStr;\n");
  5499. outf("\tOwned<IEsp%s> iserv = (IEsp%s*)getService();\n", name_, name_);
  5500. outs("\tif(iserv == NULL)\n");
  5501. outs("\t{\n");
  5502. outs("\t\trespStr.append(\"Service not available\");\n");
  5503. outs("\t\tresponse->setContent(respStr.str());\n");
  5504. outs("\t\tresponse->setContentType(\"text/html\");\n");
  5505. outs("\t\tresponse->send();\n");
  5506. outs("\t}\n");
  5507. outs("\telse\n");
  5508. outs("\t{\n");
  5509. outf("\t\tOwned<CSoapResponseBinding> esp_response;\n");
  5510. outf("\t\tStringBuffer source;\n");
  5511. outf("\t\tIEspContext& context = *request->queryContext();\n");
  5512. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5513. {
  5514. bool bClientXslt=false;
  5515. const char *respXsl = mthi->getMetaString("resp_xsl_default", NULL);
  5516. const char *respContentType = mthi->getMetaString("http_content_type", "\"text/html\"");
  5517. if (!respXsl)
  5518. {
  5519. respXsl = mthi->getMetaString("client_xslt", NULL);
  5520. bClientXslt=(respXsl!=NULL);
  5521. }
  5522. StrBuffer clearCacheGroupIDs;
  5523. if (mthi->hasMetaTag("clear_cache_group"))
  5524. {
  5525. StrBuffer cCGIDs;
  5526. mthi->getMetaStringValue(cCGIDs,"clear_cache_group");
  5527. if (cacheDefined || (cCGIDs.length() != 0))
  5528. clearCacheGroupIDs.set((cCGIDs.length() != 0) ? cCGIDs.str() : serviceCacheGroupID.str());
  5529. }
  5530. bool bHandleExceptions = 0 != mthi->getMetaInt("exceptions_inline", 0) || mthi->getMetaInt("http_exceptions_inline", 0);
  5531. if (!bHandleExceptions)
  5532. bHandleExceptions = 0 != getMetaInt("exceptions_inline", 0) || getMetaInt("http_exceptions_inline", 0);
  5533. if (respXsl==NULL)
  5534. {
  5535. outf("\t\tif(!stricmp(method, \"%s\")||!stricmp(method, \"%s\"))\n", mthi->getName(), mthi->getReq());
  5536. outs("\t\t{\n");
  5537. outf("\t\t\tOwned<C%s> esp_request = new C%s(&context, \"%s\", request->queryParameters(), request->queryAttachments());\n", mthi->getReq(), mthi->getReq(), name_);
  5538. outf("\t\t\tcheckRequest(context);\n");
  5539. outf("\t\t\tC%s* resp = new C%s(\"%s\");\n", mthi->getResp(), mthi->getResp(), name_);
  5540. outf("\t\t\tesp_response.setown(resp);\n");
  5541. writeAccessMap(3, *this, name_, servicefeatureurl, *mthi);
  5542. if (bHandleExceptions)
  5543. {
  5544. outf("\t\t\tsource.setf(\"%s::%%s()\", method);\n", name_);
  5545. outf("\t\t\tOwned<IMultiException> me = MakeMultiException(source.str());\n");
  5546. //begin try block
  5547. outs("\t\t\ttry\n");
  5548. outs("\t\t\t{\n");
  5549. if (servicefeatureurl.length() != 0)
  5550. outf("\t\t\t\tif(accessmap.ordinality()>0)\n\t\t\t\t\tonFeaturesAuthorize(context, accessmap, \"%s\", \"%s\");\n", name_, mthi->getName());
  5551. if (mthi->getMetaInt("do_not_log",0))
  5552. outf("\t\t\t\tcontext.queryRequestParameters()->setProp(\"do_not_log\",1);\n");
  5553. outf("\t\t\t\tiserv->on%s(context, *esp_request.get(), *resp);\n", mthi->getName());
  5554. if (clearCacheGroupIDs.length() > 0)
  5555. outf("\t\t\t\tclearCacheByGroupID(\"%s\");\n", clearCacheGroupIDs.str());
  5556. outs("\t\t\t}\n");
  5557. write_catch_blocks(mthi, ct_httpresp, 3);
  5558. }
  5559. else
  5560. {
  5561. if (servicefeatureurl.length() != 0)
  5562. outf("\t\t\tif(accessmap.ordinality()>0)\n\t\t\t\tonFeaturesAuthorize(context, accessmap, \"%s\", \"%s\");\n", name_, mthi->getName());
  5563. outf("\t\t\tiserv->on%s(*request->queryContext(), *esp_request.get(), *resp);\n", mthi->getName());
  5564. if (clearCacheGroupIDs.length() > 0)
  5565. outf("\t\t\tclearCacheByGroupID(\"%s\");\n", clearCacheGroupIDs.str());
  5566. }
  5567. outs("\t\t}\n");
  5568. }
  5569. else
  5570. {
  5571. outf("\t\tif(!stricmp(method, \"%s\")||!stricmp(method, \"%s\"))\n", mthi->getName(), mthi->getReq());
  5572. outs("\t\t{\n");
  5573. outf("\t\t\tOwned<C%s> esp_request = new C%s(&context, \"%s\", request->queryParameters(), request->queryAttachments());\n", mthi->getReq(), mthi->getReq(), name_);
  5574. outf("\t\t\tcheckRequest(context);\n");
  5575. outf("\t\t\tOwned<C%s> esp_response = new C%s(\"%s\");\n", mthi->getResp(), mthi->getResp(), name_);
  5576. if (bHandleExceptions)
  5577. {
  5578. outs("\t\t\tStringBuffer source;\n");
  5579. outf("\t\t\tsource.appendf(\"%s::%%s()\", method);\n", name_);
  5580. outf("\t\t\tOwned<IMultiException> me = MakeMultiException(source.str());\n");
  5581. //begin try block
  5582. outs("\t\t\ttry\n");
  5583. outs("\t\t\t{\n");
  5584. outf("\t\t\t\tiserv->on%s(*request->queryContext(), *esp_request.get(), *esp_response.get());\n", mthi->getName());
  5585. if (clearCacheGroupIDs.length() > 0)
  5586. outf("\t\t\t\tclearCacheByGroupID(\"%s\");\n", clearCacheGroupIDs.str());
  5587. outs("\t\t\t}\n");
  5588. write_catch_blocks(mthi, ct_httpresp,3);
  5589. }
  5590. else
  5591. {
  5592. outf("\t\t\t\tiserv->on%s(*request->queryContext(), *esp_request.get(), *esp_response.get());\n", mthi->getName());
  5593. if (clearCacheGroupIDs.length() > 0)
  5594. outf("\t\t\tclearCacheByGroupID(\"%s\");\n", clearCacheGroupIDs.str());
  5595. }
  5596. outs("\t\t\tif (canRedirect(*request) && esp_response->getRedirectUrl() && *esp_response->getRedirectUrl())\n");
  5597. outs("\t\t\t{\n");
  5598. outs("\t\t\t\tresponse->redirect(*request, esp_response->getRedirectUrl());\n");
  5599. outs("\t\t\t}\n");
  5600. outs("\t\t\telse\n");
  5601. outs("\t\t\t{\n");
  5602. outs("\t\t\t\tIProperties *props=request->queryParameters();\n");
  5603. outs("\t\t\t\tif (skipXslt(context))\n");
  5604. outs("\t\t\t\t{\n");
  5605. outs("\t\t\t\t\tMemoryBuffer content;\n");
  5606. outs("\t\t\t\t\tStringBuffer mimetype;\n");
  5607. outs("\t\t\t\t\tesp_response->appendContent(&context,content, mimetype);\n");
  5608. outs("\t\t\t\t\tonBeforeSendResponse(context,request,content,service,method);\n");
  5609. outs("\t\t\t\t\tresponse->setContent(content.length(), content.toByteArray());\n");
  5610. outs("\t\t\t\t\tresponse->setContentType(mimetype.str());\n");
  5611. outs("\t\t\t\t}\n");
  5612. outs("\t\t\t\telse\n");
  5613. outs("\t\t\t\t{\n");
  5614. outs("\t\t\t\t\tStringBuffer xml;\n");
  5615. outs("\t\t\t\t\tStringBuffer sResponse;\n");
  5616. if (bClientXslt)
  5617. {
  5618. outs("\t\t\t\t\tif (request->supportClientXslt())\n");
  5619. outf("\t\t\t\t\t\txml.appendf(\"<?xml version=\\\"1.0\\\" encoding=\\\"UTF-8\\\"?><?xml-stylesheet type=\\\"text/xsl\\\" href=\\\"%%s\\\"?>\", %s);\n", respXsl);
  5620. }
  5621. outs("\t\t\t\t\tesp_response->serializeStruct(&context, xml, NULL);\n\n");
  5622. if (bClientXslt)
  5623. {
  5624. outs("\t\t\t\t\tif (request->supportClientXslt()){\n");
  5625. outs("\t\t\t\t\t\txml.swapWith(sResponse);\n");
  5626. outs("\t\t\t\t\t\tresponse->setContentType(\"text/xml\");\n");
  5627. outs("\t\t\t\t\t}else{\n");
  5628. }
  5629. if(respXsl[1] == '/')
  5630. {
  5631. outf("\t\t\t\t\txslTransform(xml.str(), %s, sResponse.clear(), context.queryXslParameters());\n", respXsl);
  5632. }
  5633. else
  5634. {
  5635. outf("\t\t\t\t\txslTransform(xml.str(), StringBuffer(getCFD()).append(%s).str(), sResponse.clear(), context.queryXslParameters());\n", respXsl);
  5636. }
  5637. outf("\t\t\t\t\tresponse->setContentType(%s);\n", respContentType);
  5638. needsXslt = true;
  5639. if (bClientXslt)
  5640. outs("\t\t\t\t\t}\n");
  5641. outs("\t\t\t\t\tresponse->setContent(sResponse.str());\n");
  5642. outs("\t\t\t\t}\n");
  5643. outs("\t\t\t\tresponse->send();\n");
  5644. outs("\t\t\t}\n");
  5645. outs("\t\t\treturn 0;\n");
  5646. outs("\t\t}\n");
  5647. }
  5648. }
  5649. outs("\n");
  5650. indentReset(2);
  5651. indentOuts("if (esp_response.get())\n");
  5652. indentOuts("{\n");
  5653. indentOuts(1,"if (canRedirect(*request) && esp_response->getRedirectUrl() && *esp_response->getRedirectUrl())\n");
  5654. indentOuts(1,"response->redirect(*request, esp_response->getRedirectUrl());\n");
  5655. indentOuts(-1,"else\n");
  5656. indentOuts("{\n");
  5657. indentOuts(1,"MemoryBuffer content;\n");
  5658. indentOuts("StringBuffer mimetype;\n");
  5659. indentOuts("esp_response->appendContent(&context,content, mimetype);\n");
  5660. indentOuts("onBeforeSendResponse(context,request,content,service,method);\n");
  5661. indentOuts("response->setContent(content.length(), content.toByteArray());\n");
  5662. indentOuts("response->setContentType(mimetype.str());\n");
  5663. indentOuts("response->send();\n");
  5664. indentOuts(-1,"}\n");
  5665. indentOuts("return 0;\n");
  5666. indentOuts(-1,"}\n");
  5667. outs("\t}\n");
  5668. outs("\treturn onGetNotFound(context, request, response, service);\n");
  5669. outs("}\n");
  5670. }
  5671. //-------------------------------------------------------------------------------------------------------------
  5672. // class EspServInfo
  5673. void EspServInfo::write_catch_blocks(EspMethodInfo* mthi, catch_type ct, int indents)
  5674. {
  5675. const char* errorXslt=NULL;
  5676. if (ct==ct_httpresp)
  5677. {
  5678. errorXslt = mthi->getMetaString("exceptions_inline", NULL);
  5679. if (!errorXslt)
  5680. errorXslt = mthi->getMetaString("http_exceptions_inline", NULL);
  5681. if (!errorXslt)
  5682. errorXslt = getMetaString("exceptions_inline", NULL);
  5683. if (!errorXslt)
  5684. errorXslt = getMetaString("http_exceptions_inline", NULL);
  5685. }
  5686. outs(indents,"catch (IMultiException* mex)\n");
  5687. outs(indents,"{\n");
  5688. outs(indents+1,"me->append(*mex);\n");
  5689. outs(indents+1,"mex->Release();\n");
  5690. outs(indents,"}\n");
  5691. //catch IException
  5692. outs(indents,"catch (IException* e)\n");
  5693. outs(indents,"{\n");
  5694. outs(indents+1,"me->append(*e);\n");
  5695. outs(indents,"}\n");
  5696. //catch ...
  5697. outs(indents,"catch (...)\n");
  5698. outs(indents,"{\n");
  5699. outs(indents+1,"me->append(*MakeStringExceptionDirect(-1, \"Unknown Exception\"));\n");
  5700. outs(indents,"}\n");
  5701. //apply any xslt on the error(s), if it is specified in scm file
  5702. //
  5703. if (errorXslt)
  5704. {
  5705. if(errorXslt[1] == '/')
  5706. {
  5707. outf(indents, "if (response->handleExceptions(xslp, me, \"%s\", \"%s\", %s))\n", name_, mthi->getName(), errorXslt);
  5708. }
  5709. else
  5710. {
  5711. outf(indents, "if (response->handleExceptions(xslp, me, \"%s\", \"%s\", StringBuffer(getCFD()).append(%s).str()))\n", name_, mthi->getName(), errorXslt);
  5712. }
  5713. outs(indents+1, "return 0;\n");
  5714. needsXslt=true;
  5715. }
  5716. else
  5717. outf(indents, "esp_response->handleExceptions(me, \"%s\", \"%s\");\n", name_, mthi->getName());
  5718. }
  5719. void EspServInfo::write_esp_service_ipp()
  5720. {
  5721. outf("class C%s : public CInterface,\n", name_);
  5722. outf("\timplements IEsp%s\n", name_);
  5723. outs("{\n");
  5724. outs("private:\n");
  5725. outs("\tIEspContainer* m_container;\n");
  5726. outs("public:\n");
  5727. outs("\tIMPLEMENT_IINTERFACE;\n\n");
  5728. outf("\tC%s(){}\n\tvirtual ~C%s(){}\n", name_, name_);
  5729. outs("\tvirtual void init(IPropertyTree *cfg, const char *process, const char *service)\n\t{\n\t}\n");
  5730. outs("\tvirtual bool init(const char * service, const char * type, IPropertyTree * cfg, const char * process)\n\t{\n\t\treturn true;\n\t}\n");
  5731. outs("\tvirtual void setContainer(IEspContainer *c)\n\t{\n\t\tm_container = c;\n\t}\n");
  5732. outs("\tvirtual IEspContainer *queryContainer()\n\t{\n\t\treturn m_container;\n\t}\n");
  5733. outf("\tvirtual const char* getServiceType(){return \"%s\";}\n\n", name_);
  5734. outf("\tvirtual bool unsubscribeServiceFromDali(){return false;}\n\n");
  5735. outf("\tvirtual bool subscribeServiceToDali(){return false;}\n\n");
  5736. outf("\tvirtual bool detachServiceFromDali(){return false;}\n\n");
  5737. outf("\tvirtual bool attachServiceToDali(){return false;}\n\n");
  5738. outf("\tvirtual bool canDetachFromDali(){return false;}\n\n");
  5739. EspMethodInfo *mthi;
  5740. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5741. {
  5742. bool stubbed = (findMetaTag(mthi->tags,"stubbed")!=NULL);
  5743. if (streq(mthi->getName(), "Ping")) //We'll implement the onPing automatically for all ESP Services.
  5744. {
  5745. outf(1, "bool on%s(IEspContext &context, IEsp%s &req, IEsp%s &resp)\n", mthi->getName(), mthi->getReq(), mthi->getResp());
  5746. outs(1, "{\n");
  5747. outs(2, "return true;\n");
  5748. outs(1, "}\n");
  5749. }
  5750. else
  5751. {
  5752. outf(1, "%sbool on%s(IEspContext &context, IEsp%s &req, IEsp%s &resp)\n", (stubbed) ? "" : "//", mthi->getName(), mthi->getReq(), mthi->getResp());
  5753. outf(1, "%s{\n", (stubbed) ? "" : "//");
  5754. outf(2, "%sreturn false;\n", (stubbed) ? "" : "//");
  5755. outf(1, "%s}\n", (stubbed) ? "" : "//");
  5756. }
  5757. }
  5758. outs("};\n\n");
  5759. }
  5760. void EspServInfo::write_esp_service()
  5761. {
  5762. }
  5763. void EspServInfo::write_esp_client_ipp()
  5764. {
  5765. int useMethodName = getMetaInt("use_method_name", 0);
  5766. outf("class CClient%s : public CInterface,\n", name_);
  5767. outf("\timplements IClient%s\n", name_);
  5768. outs("{\nprotected:\n");
  5769. outs("\tStringBuffer soap_proxy;\n");
  5770. outs("\tStringBuffer soap_url;\n");
  5771. //dom
  5772. outs("\tStringBuffer soap_userid;\n");
  5773. outs("\tStringBuffer soap_password;\n");
  5774. outs("\tStringBuffer soap_realm;\n");
  5775. outs("\tStringBuffer soap_action;\n");
  5776. outs("\tlong soap_reqid = 0;\n");
  5777. outs("\npublic:\n");
  5778. outs("\tIMPLEMENT_IINTERFACE;\n\n");
  5779. outf("\tCClient%s()\n\t{\n", name_);
  5780. outs("\t\tsoap_reqid=0;\n\t");
  5781. outf("\t\tsoap_action.append(\"%s\");\n\t", name_);
  5782. const char *ver = getMetaString("default_client_version", NULL);
  5783. if (ver && *ver)
  5784. outf("\t\tsoap_action.append(\"?ver_=\").append(%s);\n\t", ver);
  5785. outf("}\n\tvirtual ~CClient%s(){}\n", name_);
  5786. outs("\tvirtual void setProxyAddress(const char *address)\n\t{\n\t\tsoap_proxy.set(address);\n\t}\n");
  5787. outs("\tvirtual void addServiceUrl(const char *url)\n\t{\n\t\tsoap_url.set(url);\n\t}\n");
  5788. outs("\tvirtual void removeServiceUrl(const char *url)\n\t{\n\t}\n");
  5789. //domsetUsernameToken
  5790. outs("\tvirtual void setUsernameToken(const char *userid,const char *password,const char *realm)\n\t{\n\t\t soap_userid.set(userid);\n\t\t soap_password.set(password);\n\t\t soap_realm.set(realm);\n\t}\n");
  5791. outs("\tvirtual void setAction(const char *action)\n\t{\n\t\tsoap_action.set(action);\n\t}\n");
  5792. EspMethodInfo *mthi;
  5793. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5794. {
  5795. outs("\n");
  5796. outf("\tvirtual IClient%s * create%sRequest();\n", mthi->getReq(), mthi->getName());
  5797. outf("\tvirtual IClient%s * %s(IClient%s *request);\n", mthi->getResp(), mthi->getName(), mthi->getReq());
  5798. outf("\tvirtual void async_%s(IClient%s *request, IClient%sEvents *events,IInterface* state=0);\n", mthi->getName(), mthi->getReq(), name_);
  5799. mthi->write_esp_method(name_, true, false);
  5800. }
  5801. outs("\tstatic int transferThunkEvent(void *data);\n");
  5802. outs("#ifdef _WIN32\n");
  5803. outs("\tstatic void espWorkerThread(void* data);\n");
  5804. outs("#else\n");
  5805. outs("\tstatic void *espWorkerThread(void *data);\n");
  5806. outs("#endif\n");
  5807. outs("};\n\n");
  5808. }
  5809. void EspServInfo::write_esp_client()
  5810. {
  5811. int useMethodName = getMetaInt("use_method_name", 0);
  5812. //comment
  5813. outs("\n//=======================================================");
  5814. outs("\n// client util methods");
  5815. outs("\n//=======================================================");
  5816. outs("\n");
  5817. EspMethodInfo *mthi;
  5818. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5819. {
  5820. outf("\n//------ method %s ---------\n", mthi->getName());
  5821. outf("\nIClient%s * CClient%s::create%sRequest()\n", mthi->getReq(), name_, mthi->getName());
  5822. outf("{\n\tC%s* request = new C%s(\"%s\");\n", mthi->getReq(), mthi->getReq(), name_);
  5823. outs("\trequest->setProxyAddress(soap_proxy.str());\n");
  5824. outs("\trequest->setUrl(soap_url.str());\n");
  5825. if (useMethodName)
  5826. outf("\trequest->setMsgName(\"%s\");\n", mthi->getName());
  5827. outs("\treturn request;\n}\n");
  5828. outf("\nIClient%s * CClient%s::%s(IClient%s *request)\n", mthi->getResp(), name_, mthi->getName(), mthi->getReq());
  5829. outs("{\n");
  5830. outs("\tif(soap_url.length()== 0){ throw MakeStringExceptionDirect(-1, \"url not set\"); }\n\n");
  5831. outf("\tC%s* esprequest = static_cast<C%s*>(request);\n", mthi->getReq(), mthi->getReq());
  5832. outf("\tC%s* espresponse = new C%s(\"%s\");\n\n", mthi->getResp(), mthi->getResp(), name_);
  5833. outs("\tespresponse->setReqId(soap_reqid++);\n");
  5834. //dom
  5835. outs("\tesprequest->soap_setUserId( soap_userid.str());\n");
  5836. outs("\tesprequest->soap_setPassword(soap_password.str());\n");
  5837. outs("\tesprequest->soap_setRealm(soap_realm.str());\n");
  5838. outs("\tconst char *soapaction=(soap_action.length()) ? soap_action.str() : NULL;\n");
  5839. outs("\tesprequest->post(soap_proxy.str(), soap_url.str(), *espresponse, soapaction);\n");
  5840. outs("\treturn espresponse;\n");
  5841. outs("}\n");
  5842. outf("\nvoid CClient%s::async_%s(IClient%s *request, IClient%sEvents *events,IInterface* state)\n", name_, mthi->getName(), mthi->getReq(), name_);
  5843. outs("{\n");
  5844. outs("\tif(soap_url.length()==0){ throw MakeStringExceptionDirect(-1, \"url not set\"); }\n\n");
  5845. outf("\tC%s* esprequest = static_cast<C%s*>(request);\n", mthi->getReq(), mthi->getReq());
  5846. outf("\tesprequest->setMethod(\"%s\");\n", mthi->getName());
  5847. outs("\tesprequest->setReqId(soap_reqid++);\n");
  5848. outs("\tesprequest->setEventSink(events);\n");
  5849. outs("\tesprequest->setState(state);\n");
  5850. outs("\tesprequest->soap_setUserId( soap_userid.str());\n");
  5851. outs("\tesprequest->soap_setPassword( soap_password.str());\n");
  5852. outs("\tesprequest->soap_setRealm( soap_realm.str());\n");
  5853. outs("#ifdef USE_CLIENT_THREAD\n");
  5854. outs("\tesprequest->setThunkHandle(GetThunkingHandle());\n");
  5855. outs("#endif\n");
  5856. outs("\tesprequest->Link();\n\n");
  5857. outs("\tif(state!=NULL)\n");
  5858. outs("\t\tstate->Link();\n\n");
  5859. outs("#ifdef _WIN32\n");
  5860. outs("\t_beginthread(espWorkerThread, 0, (void *)(IRpcRequestBinding *)(esprequest));\n");
  5861. outs("#else\n");
  5862. outs("\tpthread_attr_t attr;\n");
  5863. outs("\tpthread_attr_init(&attr);\n");
  5864. outs("\tpthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);\n");
  5865. outs("\tpthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);\n");
  5866. outs("\tpthread_attr_setstacksize(&attr, 0x10000);\n");
  5867. outs("\tThreadId threadid;\n");
  5868. outs("\tint status;\n");
  5869. outs("\tdo\n");
  5870. outs("\t{\n");
  5871. outf("\t\tstatus = pthread_create(&threadid, &attr, CClient%s::espWorkerThread, (void *)(IRpcRequestBinding *)(esprequest));\n", name_);
  5872. outs("\t} while (0 != status && (errno == EINTR));\n");
  5873. outs("\tif (status) {\n");
  5874. outs("\t\tRelease();\n");
  5875. outs("\t\tthrow makeOsException(errno);\n");
  5876. outs("\t}\n");
  5877. outs("#endif\n");
  5878. outs("}\n");
  5879. mthi->write_esp_method(name_, false, false);
  5880. }
  5881. outf("\nint CClient%s::transferThunkEvent(void *data)\n", name_);
  5882. outs("{\n");
  5883. outs("\tIRpcResponseBinding *response = (IRpcResponseBinding *)data;\n");
  5884. outs("\tif (response!=NULL)\n");
  5885. outs("\t{\n");
  5886. outf("\t\tIClient%sEvents *eventSink = (IClient%sEvents *)response->getEventSink();\n", name_, name_);
  5887. outs("\t\tresponse->lock();\n\n");
  5888. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5889. {
  5890. outf(2, "if (stricmp(response->getMethod(), \"%s\")==0)\n", mthi->getName());
  5891. outs(2, "{\n");
  5892. outf(3, "IClient%s* icresp = dynamic_cast<IClient%s*>(response);\n", mthi->getResp(), mthi->getResp());
  5893. outf(3, "if (icresp) {\n");
  5894. outs(4, "if (response->getRpcState() == RPC_MESSAGE_OK)\n");
  5895. outf(5, "eventSink->on%sComplete(icresp, response->queryState());\n", mthi->getName());
  5896. outf(4, "else\n");
  5897. outf(5, "eventSink->on%sError(icresp,response->queryState());\n", mthi->getName());
  5898. outs(3, "}\n");
  5899. outs(2, "}\n");
  5900. }
  5901. outs("\t\tresponse->unlock();\n");
  5902. outs("\t}\n");
  5903. outs("\treturn 0;\n");
  5904. outs("}\n");
  5905. //=============================================================================
  5906. // method: espWorkerThread(void* data)
  5907. outf("\nstatic IRpcResponseBinding* create%sResponseObject(IRpcRequestBinding *request)\n",name_);
  5908. outs("{\n");
  5909. outs("\tconst char* method = request->getMethod();\n");
  5910. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5911. {
  5912. outf("\tif (stricmp(method, \"%s\")==0)\n", mthi->getName());
  5913. outf("\t\treturn new C%s(\"%s\", request);\n", mthi->getResp(), name_);
  5914. }
  5915. outf("\treturn NULL;\n");
  5916. outs("}\n");
  5917. outf("\n#ifdef _WIN32\n");
  5918. outf("void CClient%s::espWorkerThread(void* data)\n", name_);
  5919. outf("#else\n");
  5920. outf("void *CClient%s::espWorkerThread(void *data)\n", name_);
  5921. outf("#endif\n");
  5922. outs("{\n");
  5923. outs("\tIRpcRequestBinding *request = (IRpcRequestBinding *) data;\n\n");
  5924. outs("\tif (request != NULL)\n");
  5925. outs("\t{\n");
  5926. outs("\t\trequest->lock();\n");
  5927. outf("\t\tIRpcResponseBinding *response=create%sResponseObject(request);\n",name_);
  5928. /*
  5929. const char *preif="";
  5930. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5931. {
  5932. outf("\t\t%sif (stricmp(request->getMethod(), \"%s\")==0)\n\t\t{\n", preif, mthi->getName());
  5933. outf("\t\t\tresponse = new C%s(\"%s\", request);\n\t\t}\n", mthi->getResp(), name_);
  5934. preif="else ";
  5935. }
  5936. outf("\tresponse = createResponseObject(request);\n");
  5937. */
  5938. outs(2, "if (response!=NULL)\n");
  5939. outs(2, "{\n");
  5940. outs(3, "try{\n");
  5941. outs(4, "request->post(*response);\n");
  5942. outs(3, "}\n");
  5943. outs(3, "catch(IException* ex){\n");
  5944. outs(4, "StringBuffer errorStr;\n");
  5945. outs(4, "ex->errorMessage(errorStr);\n");
  5946. outf(4, "ERRLOG(\"CClient%s::espWorkerThread(%%s)--Exception caught while posting async request: %%s\", request->getMethod(), errorStr.str());\n", name_);
  5947. outs(4, "ex->Release();\n");
  5948. outs(3, "}\n");
  5949. outs(3, "catch(...){\n");
  5950. outs(4, "ERRLOG(\"Unknown exception caught while posting async request\");\n");
  5951. outs(3, "}\n");
  5952. outs(2, "}\n");
  5953. outs("#ifdef USE_CLIENT_THREAD\n");
  5954. outs("\t\tThunkToClientThread(request->getThunkHandle(), transferThunkEvent, (void *)response);\n");
  5955. outs("#else\n");
  5956. outs("\t\ttransferThunkEvent((void *)response);\n");
  5957. outs("#endif\n");
  5958. outs("\t\trequest->unlock();\n");
  5959. outs("\t\tif(request->queryState()!=NULL)\n");
  5960. outs("\t\t\trequest->queryState()->Release();\n\n");
  5961. outs("\t\tif(response!=NULL)\n");
  5962. outs("\t\t\tresponse->Release();\n\n");
  5963. outs("\t\trequest->Release();\n");
  5964. outs("\t}\n");
  5965. outs("#if defined(_WIN32)\n");
  5966. outs("#else\n");
  5967. outs("\treturn (void *) 0 ;\n");
  5968. outs("#endif\n");
  5969. outs("}\n\n");
  5970. }
  5971. void EspServInfo::write_clarion_include_interface()
  5972. {
  5973. outf("cppClient%sEvents INTERFACE(cppInterface),COM\n", name_);
  5974. EspMethodInfo *mthi;
  5975. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5976. {
  5977. outf("on%sComplete PROCEDURE(*cppClient%s resp),PROC\n", mthi->getName(), mthi->getResp());
  5978. outf("on%sError PROCEDURE(*cppClient%s resp),PROC\n", mthi->getName(), mthi->getResp());
  5979. }
  5980. outs("\n END\n\n");
  5981. outf("cppClient%s INTERFACE(cppInterface),COM\n", name_);
  5982. outs("setProxyAddress PROCEDURE(CONST *CSTRING address),PROC\n");
  5983. outs("addServiceUrl PROCEDURE(CONST *CSTRING url),PROC\n");
  5984. outs("removeServiceUrl PROCEDURE(CONST *CSTRING url),PROC\n");
  5985. outs("setUsernameToken PROCEDURE(CONST *CSTRING Username,CONST *CSTRING Password,CONST *CSTRING Realm ),PROC\n");
  5986. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  5987. {
  5988. outf("create%sRequest PROCEDURE(),*cppClient%s,PROC\n", mthi->getName(), mthi->getReq());//mthi->getName());
  5989. outf("%s PROCEDURE(*cppClient%s request),*cppClient%s,PROC\n", mthi->getName(), mthi->getReq(), mthi->getResp());
  5990. outf("async_%s PROCEDURE(*cppClient%s request, *cppClient%sEvents events,*cppInterface State),PROC\n", mthi->getName(), mthi->getReq(), name_);
  5991. }
  5992. outs("\n END\n\n");
  5993. }
  5994. //interface IEspInstantEcl
  5995. void EspServInfo::write_event_interface()
  5996. {
  5997. outf("interface IClient%sEvents : extends IInterface\n", name_);
  5998. outs("{");
  5999. EspMethodInfo *mthi;
  6000. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  6001. {
  6002. outs("\n");
  6003. outf("\tvirtual int on%sComplete(IClient%s *resp,IInterface* state)=0;\n", mthi->getName(), mthi->getResp());
  6004. outf("\tvirtual int on%sError(IClient%s *resp,IInterface* state)=0;", mthi->getName(), mthi->getResp());
  6005. }
  6006. outs("\n};\n\n");
  6007. }
  6008. void EspServInfo::write_esp_interface()
  6009. {
  6010. outf("interface IEsp%s : extends IEspService\n", name_);
  6011. outs("{");
  6012. EspMethodInfo *mthi;
  6013. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  6014. {
  6015. outs("\n");
  6016. outf("\tvirtual bool on%s(IEspContext &context, IEsp%s &req, IEsp%s &resp)=0;", mthi->getName(), mthi->getReq(), mthi->getResp());
  6017. }
  6018. outs("\n};\n\n");
  6019. }
  6020. void EspServInfo::write_client_interface()
  6021. {
  6022. outf("interface IClient%s : extends IInterface\n", name_);
  6023. outs("{\n");
  6024. outs("\tvirtual void setProxyAddress(const char *address)=0;\n");
  6025. outs("\tvirtual void addServiceUrl(const char *url)=0;\n");
  6026. outs("\tvirtual void removeServiceUrl(const char *url)=0;\n");
  6027. outs("\tvirtual void setUsernameToken(const char *userName,const char *passWord,const char *realm)=0;\n");
  6028. outs("\tvirtual void setAction(const char *action)=0;\n");
  6029. EspMethodInfo *mthi;
  6030. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  6031. {
  6032. outs("\n");
  6033. outf("\tvirtual IClient%s * create%sRequest()=0;\n", mthi->getReq(), mthi->getName());
  6034. outf("\tvirtual IClient%s * %s(IClient%s *request)=0;\n", mthi->getResp(), mthi->getName(), mthi->getReq());
  6035. outf("\tvirtual void async_%s(IClient%s *request, IClient%sEvents *events,IInterface* state=0)=0;\n", mthi->getName(), mthi->getReq(), name_);
  6036. }
  6037. //add the new "flattened" client methods at the end
  6038. outs("\n");
  6039. for (mthi=methods;mthi!=NULL;mthi=mthi->next)
  6040. {
  6041. mthi->write_esp_method(name_, true, true);
  6042. }
  6043. outs("};\n\n");
  6044. }
  6045. static EspMethodInfo* sortMethods(EspMethodInfo* ms)
  6046. {
  6047. if (ms==NULL)
  6048. return ms;
  6049. // find the smallest node
  6050. EspMethodInfo* smallest = ms;
  6051. EspMethodInfo* prev = NULL; // the node right before the smallest node
  6052. for (EspMethodInfo* p = ms; p->next!=NULL; p = p->next)
  6053. {
  6054. if (strcmp(p->next->getName(), smallest->getName())<0)
  6055. {
  6056. prev = p;
  6057. smallest = p->next;
  6058. }
  6059. }
  6060. // move the smallest to the head
  6061. if (smallest != ms)
  6062. {
  6063. if (prev == ms)
  6064. {
  6065. ms->next = smallest->next;
  6066. smallest->next = ms;
  6067. }
  6068. else
  6069. {
  6070. EspMethodInfo* tmp = smallest->next;
  6071. smallest->next = ms->next;
  6072. prev->next = ms;
  6073. ms->next = tmp;
  6074. }
  6075. }
  6076. // recurively sort
  6077. smallest->next = sortMethods(smallest->next);
  6078. return smallest;
  6079. }
  6080. void EspServInfo::sortMethods()
  6081. {
  6082. methods = ::sortMethods(methods);
  6083. }
  6084. //-------------------------------------------------------------------------------------------------------------
  6085. // class HIDLcompiler
  6086. char* getTargetBase(const char* outDir, const char* src)
  6087. {
  6088. if (outDir && *outDir)
  6089. {
  6090. size_t dirlen = strlen(outDir);
  6091. size_t srclen = strlen(src);
  6092. char* buf = (char*)malloc(dirlen+srclen+5);
  6093. // get file name only
  6094. const char* p = src+srclen-1;
  6095. while(p>src && *p!='/' && *p!='\\') p--;
  6096. if (*p == '/' || *p == '\\') p++;
  6097. // absolute path
  6098. if (*outDir=='/' || *outDir=='\\' || outDir[1]==':')
  6099. {
  6100. // dir: outDir+'/'+fileName
  6101. strcpy(buf,outDir);
  6102. }
  6103. else // relative path
  6104. {
  6105. // dir: srcPath + '/' + outDir+'/'+fileName
  6106. size_t len = p-src;
  6107. if (len>0)
  6108. {
  6109. strncpy(buf,src,len);
  6110. if (buf[len-1]=='/' || buf[len-1]=='\\')
  6111. buf[len-1]='/';
  6112. else
  6113. buf[len++] = '/';
  6114. }
  6115. strcpy(buf+len,outDir);
  6116. }
  6117. size_t len = strlen(buf);
  6118. if (buf[len-1]=='/' || buf[len-1]=='\\')
  6119. {
  6120. buf[len-1]=0;
  6121. len--;
  6122. }
  6123. // now buf has the directory name for output: make the directory if not exist
  6124. createDirectory(buf);
  6125. // copy the file name
  6126. buf[len] = '/';
  6127. strcpy(buf+len+1, p);
  6128. //printf("src: %s. dir: %s.\n", src,outDir);
  6129. //printf("buf: %s\n", buf);
  6130. return buf;
  6131. }
  6132. else
  6133. return strdup(src);
  6134. }
  6135. static void safeclose(int fh)
  6136. {
  6137. if (fh >= 0)
  6138. close(fh);
  6139. }
  6140. HIDLcompiler::HIDLcompiler(const char * sourceFile,const char *outDir)
  6141. {
  6142. modules = NULL;
  6143. enums = NULL;
  6144. apis = NULL;
  6145. servs = NULL;
  6146. msgs = NULL;
  6147. includes = NULL;
  6148. filename = strdup(sourceFile);
  6149. size_t l = strlen(filename);
  6150. yyin = fopen(sourceFile, "rt");
  6151. if (!yyin) {
  6152. printf("Fatal Error: Cannot read %s\n",sourceFile);
  6153. exit(1);
  6154. }
  6155. packagename = gettail(sourceFile);
  6156. char* targetBase = getTargetBase(outDir, sourceFile);
  6157. ho = createFile(targetBase,"hpp");
  6158. cppo = createFile(targetBase, isSCM ? "ipp" : "cpp");
  6159. #if 0
  6160. xsvo = createFile(targetBase, "xsv");
  6161. #endif
  6162. clwo = createFile(targetBase, "int");
  6163. espx = isESP ? createFile(targetBase,"esp") : -1;
  6164. espng = isESPng ? createFile(targetBase,"_esp_ng", "ipp") : -1;
  6165. espngc= isESPng ? createFile(targetBase,"_esp_ng", "cpp") : -1;
  6166. espi= isESP ? createFile(targetBase, "_esp", "ipp") : -1;
  6167. espc= isESP ? createFile(targetBase, "_esp", "cpp") : -1;
  6168. free(targetBase);
  6169. }
  6170. HIDLcompiler::~HIDLcompiler()
  6171. {
  6172. fclose(yyin);
  6173. close(ho);
  6174. close(cppo);
  6175. //close(xsvo);
  6176. close(clwo);
  6177. safeclose(espx);
  6178. safeclose(espng);
  6179. safeclose(espngc);
  6180. safeclose(espi);
  6181. safeclose(espc);
  6182. free(packagename);
  6183. free(filename);
  6184. delete modules;
  6185. delete enums;
  6186. delete apis;
  6187. delete msgs;
  6188. delete servs;
  6189. delete includes;
  6190. }
  6191. void HIDLcompiler::Process()
  6192. {
  6193. hcp = this;
  6194. write_header_class_intro();
  6195. nCommentStartLine = -1;
  6196. yyparse();
  6197. if (nCommentStartLine > -1)
  6198. {
  6199. char tempBuf[256];
  6200. sprintf(tempBuf, "The comment that started at line %d is not ended yet", nCommentStartLine);
  6201. yyerror(tempBuf);
  6202. }
  6203. write_header_class_outro();
  6204. write_source_file_classes();
  6205. //write_example_implementation_module();
  6206. if (isESP)
  6207. {
  6208. write_esp();
  6209. write_esp_ex_ipp();
  6210. }
  6211. if (isESPng)
  6212. {
  6213. write_esp_ng();
  6214. write_esp_ng_cpp();
  6215. }
  6216. if (isSCM)
  6217. write_clarion_HRPC_interfaces();
  6218. }
  6219. void HIDLcompiler::write_esp()
  6220. {
  6221. //create the *.esp file
  6222. gOutfile = espx;
  6223. outf("// *** Source file generated by " HIDL " Version %s from %s.%s ***\n", HIDLVER, packagename, srcFileExt);
  6224. outf("// *** Not to be hand edited (changes will be lost on re-generation) ***\n\n");
  6225. outf("#ifndef %s_ESPGEN_INCLUDED\n", packagename);
  6226. outf("#define %s_ESPGEN_INCLUDED\n\n", packagename);
  6227. outf("#include \"%s_esp.ipp\"\n", packagename);
  6228. outs("\n");
  6229. outs("#ifdef _WIN32\n");
  6230. outs("#include \"edwin.h\"\n");
  6231. outs("#include <process.h>\n");
  6232. outs("#endif\n");
  6233. outs("\n\n");
  6234. EspMessageInfo * mi;
  6235. for (mi=msgs;mi;mi=mi->next)
  6236. {
  6237. mi->write_esp();
  6238. }
  6239. EspServInfo *si;
  6240. for (si=servs;si;si=si->next)
  6241. {
  6242. si->write_esp_binding();
  6243. outs("\n\n");
  6244. si->write_esp_service();
  6245. outs("\n\n");
  6246. si->write_esp_client();
  6247. outs("\n\n");
  6248. si->write_factory_impl();
  6249. outs("\n\n");
  6250. }
  6251. outf("#endif //%s_ESPGEN_INCLUDED\n", packagename);
  6252. gOutfile = espc;
  6253. outf("// *** Source file generated by " HIDL " Version %s from %s.%s ***\n", HIDLVER, packagename, srcFileExt);
  6254. outf("// *** Not to be hand edited (changes will be lost on re-generation) ***\n\n");
  6255. //outf("#ifndef %s_ESPX_INCLUDED\n", packagename);
  6256. //outf("#define %s_ESPX_INCLUDED\n\n", packagename);
  6257. //if (esp_def_export_tag)
  6258. // outf("#include \"%s.esp\"\n", packagename);
  6259. outf("#include \"%s.esp\"\n", packagename);
  6260. outs("\n\n");
  6261. //outf("#endif //%s_ESPX_INCLUDED\n", packagename);
  6262. }
  6263. void HIDLcompiler::write_esp_ex_ipp()
  6264. {
  6265. gOutfile = espi;
  6266. outf("// *** Source file generated by " HIDL " Version %s from %s.%s ***\n", HIDLVER, packagename, srcFileExt);
  6267. outf("// *** Not to be hand edited (changes will be lost on re-generation) ***\n\n");
  6268. outf("#ifndef %s_EX_ESPGEN_INCLUDED\n", packagename);
  6269. outf("#define %s_EX_ESPGEN_INCLUDED\n\n", packagename);
  6270. outs("#pragma warning( disable : 4786)\n\n");
  6271. outs("//JLib\n");
  6272. outs("#include \"jliball.hpp\"\n");
  6273. outs("\n");
  6274. outs("//SCM Interfaces\n");
  6275. outs("#include \"esp.hpp\"\n");
  6276. outs("#include \"soapesp.hpp\"\n");
  6277. outf("#include \"%s.hpp\"\n", packagename);
  6278. outs("//ESP Bindings\n");
  6279. outs("#include \"SOAP/Platform/soapmessage.hpp\"\n");
  6280. outs("#include \"SOAP/Platform/soapmacro.hpp\"\n");
  6281. outs("#include \"SOAP/Platform/soapservice.hpp\"\n");
  6282. outs("#include \"SOAP/Platform/soapparam.hpp\"\n");
  6283. outs("#include \"SOAP/client/soapclient.hpp\"\n");
  6284. outs("\n\n");
  6285. outf("namespace %s\n{\n\n", packagename);
  6286. EspMessageInfo * mi;
  6287. for (mi=msgs;mi;mi=mi->next)
  6288. {
  6289. mi->write_esp_ipp();
  6290. }
  6291. EspServInfo *si;
  6292. for (si=servs;si;si=si->next)
  6293. {
  6294. si->write_esp_service_ipp();
  6295. outs("\n\n");
  6296. si->write_esp_binding_ipp();
  6297. outs("\n\n");
  6298. si->write_esp_client_ipp();
  6299. outs("\n\n");
  6300. }
  6301. outs("}\n");
  6302. outf("using namespace %s;\n\n", packagename);
  6303. outf("#endif //%s_ESPGEN_INCLUDED\n", packagename);
  6304. }
  6305. void HIDLcompiler::write_source_file_classes()
  6306. {
  6307. gOutfile = cppo;
  6308. outf("// *** Source file generated by " HIDL " Version %s from %s.%s ***\n", HIDLVER, packagename, srcFileExt);
  6309. outf("// *** Not to be hand edited (changes will be lost on re-generation) ***\n\n");
  6310. outf("#include \"%s.hpp\"\n\n",packagename);
  6311. ModuleInfo * mi;
  6312. for (mi=modules;mi;mi=mi->next)
  6313. {
  6314. if (isSCM) {
  6315. mi->write_clarion_scm_stub_class();
  6316. }
  6317. else {
  6318. mi->write_body_class();
  6319. mi->write_clarion_interface_class();
  6320. }
  6321. }
  6322. outs("//end\n"); // CR for Clarion
  6323. }
  6324. void HIDLcompiler::write_clarion_esp_interfaces()
  6325. {
  6326. gOutfile = clwo;
  6327. EspMessageInfo * mi;
  6328. for (mi=msgs;mi;mi=mi->next)
  6329. {
  6330. mi->write_clarion_include_interface();
  6331. outs("\n\n");
  6332. }
  6333. EspServInfo *si;
  6334. for (si=servs;si;si=si->next)
  6335. {
  6336. si->write_clarion_include_interface();
  6337. outs("\n\n");
  6338. }
  6339. }
  6340. void HIDLcompiler::write_clarion_HRPC_interfaces()
  6341. {
  6342. gOutfile = clwo;
  6343. if (isSCM)
  6344. outs("! Clarion SCM Interfaces\n");
  6345. else
  6346. {
  6347. // outs("! Clarion HRPC Interfaces\n");
  6348. outs("*** No longer generated\n");
  6349. return;
  6350. }
  6351. outf("! Include file generated by " HIDL " Version %s from %s.%s\n", HIDLVER, packagename, srcFileExt);
  6352. outs("! *** Not to be hand edited (changes will be lost on re-generation) ***\n\n");
  6353. outf(" OMIT('EndOfInclude',_%s_I_)\n",packagename);
  6354. outf("_%s_I_ EQUATE(1)\n\n",packagename);
  6355. if (isSCM)
  6356. {
  6357. outs(" INCLUDE('SCM.INT'),ONCE\n\n");
  6358. if (clarion.length())
  6359. {
  6360. outs(clarion.str());
  6361. outs("\n\n");
  6362. }
  6363. }
  6364. else
  6365. outs(" INCLUDE('HRPC.INC'),ONCE\n\n");
  6366. EnumInfo * ei;
  6367. for (ei=enums;ei;ei=ei->next)
  6368. {
  6369. ei->write_clarion_enum();
  6370. }
  6371. ModuleInfo * mi;
  6372. for (mi=modules;mi;mi=mi->next)
  6373. {
  6374. mi->write_clarion_include_module();
  6375. }
  6376. if (isESP)
  6377. {
  6378. write_clarion_esp_interfaces();
  6379. }
  6380. outs("\n");
  6381. outs(" MAP\n");
  6382. outf(" MODULE('%s')\n",packagename);
  6383. if (!isSCM)
  6384. {
  6385. for (mi=modules;mi;mi=mi->next)
  6386. {
  6387. outf(" HRPC_Make_%s(HRPCI_Clarion_Transport transport),*HRPCI_%s,PASCAL,NAME('_HRPC_Make_%s@4')\n",mi->name,mi->name,mi->name);
  6388. }
  6389. }
  6390. else
  6391. {
  6392. ApiInfo * fi;
  6393. for (fi=apis;fi;fi=fi->next)
  6394. {
  6395. fi->write_clarion_include_method();
  6396. }
  6397. }
  6398. outs(" END\n\n");
  6399. outs(" END\n\n");
  6400. outf("\nEndOfInclude\n");
  6401. }
  6402. void HIDLcompiler::write_example_implementation_module()
  6403. {
  6404. gOutfile = xsvo;
  6405. outs("// Example Server Implementation Template\n");
  6406. outf("// Source file generated by " HIDL " Version %s from %s.%s\n", HIDLVER, packagename, srcFileExt);
  6407. outs("// *** You should copy this file before changing, as it will be overwritten next time " HIDL " is run ***\n\n");
  6408. outs("#include <stddef.h>\n");
  6409. outs("#include <stdlib.h>\n");
  6410. outs("#include <assert.h>\n\n");
  6411. outs("#include \"hrpcsock.hpp\"// default use TCP/IP sockets\n\n");
  6412. outs("// TBD - Add other includes here\n\n");
  6413. ModuleInfo * mi;
  6414. for (mi=modules;mi;mi=mi->next)
  6415. {
  6416. mi->write_define();
  6417. }
  6418. outf("#include \"%s.cpp\"\n\n",packagename);
  6419. for (mi=modules;mi;mi=mi->next)
  6420. {
  6421. mi->write_example_module();
  6422. }
  6423. }
  6424. void HIDLcompiler::write_header_class_intro()
  6425. {
  6426. gOutfile=ho;
  6427. outf("// *** Include file generated by " HIDL " Version %s from %s.%s ***\n", HIDLVER, packagename, srcFileExt);
  6428. outf("// *** Not to be hand edited (changes will be lost on re-generation) ***\n\n");
  6429. outf("#ifndef %s_%s_INCL\n",packagename,isSCM?"SCM":"HID");
  6430. outf("#define %s_%s_INCL\n\n",packagename,isSCM?"SCM":"HID");
  6431. if (isESP)
  6432. {
  6433. outf("#include \"esp.hpp\"\n\n");
  6434. }
  6435. else if (isSCM)
  6436. {
  6437. //outf("#include \"scm.hpp\"\n\n");
  6438. }
  6439. else
  6440. outf("#include \"hrpc.hpp\"\n\n");
  6441. }
  6442. void HIDLcompiler::write_header_class_outro()
  6443. {
  6444. outs("\n");
  6445. EspMessageInfo * mi;
  6446. for (mi=msgs;mi;mi=mi->next)
  6447. {
  6448. mi->write_factory_decl();
  6449. }
  6450. outs("\n");
  6451. outf("#endif // _%s_%s_INCL\n", packagename,isSCM?"SCM":"HID");
  6452. outs("//end\n"); // CR for Clarion
  6453. }
  6454. //-------------------------------------------------------------------------------------------------------------
  6455. // class EnumInfo
  6456. void EnumInfo::write_header_enum()
  6457. {
  6458. outf("enum %s\n{\n", name);
  6459. for (EnumValInfo *vi=vals;vi;vi=vi->next) {
  6460. outf("\t%s = %d",vi->name,vi->val);
  6461. if (vi->next)
  6462. outs(",\n");
  6463. else
  6464. outs("\n");
  6465. }
  6466. outs("};\n\n");
  6467. }
  6468. void EnumInfo::write_clarion_enum()
  6469. {
  6470. outf("%s EQUATE(UNSIGNED)\n", xlat(name));
  6471. outf(" ITEMIZE,PRE(%s)\n",xlat(name));
  6472. for (EnumValInfo *vi=vals;vi;vi=vi->next) {
  6473. outf("%s\tEQUATE(%d)\n",xlat(vi->name),vi->val);
  6474. }
  6475. outs("\tEND\n\n");
  6476. }
  6477. // end
  6478. //-------------------------------------------------------------------------------------------------------------