home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-03-23 | 81.8 KB | 2,091 lines | [TEXT/R*ch] |
- C.S.M.P. Digest Mon, 11 Mar 96 Volume 3 : Issue 140
-
- Today's Topics:
-
- "Apple's 3-D interface guidelines" ??
- 'sysz' resources
- (Q) How to find local hard disk volumes only
- AppleEvents to-from an extension?
- Control panel code?
- DDP Listener Broadcast Problem
- Is C++ OK? Make yourself heard!
- Removing a Gestalt entry - possible?
-
-
-
- The Comp.Sys.Mac.Programmer Digest is moderated by Francois Pottier
- (pottier@clipper.ens.fr).
-
- The digest is a collection of article threads from the internet
- newsgroups comp.sys.mac.programmer.help, csmp.tools, csmp.misc and
- csmp.games. It is designed for people who read news semi-regularly and
- want an archive of the discussions. If you don't know what a
- newsgroup is, you probably don't have access to it. Ask your systems
- administrator(s) for details. If you don't have access to news, you
- may still be able to post messages to the group by using a mail server
- like anon.penet.fi (mail help@anon.penet.fi for more information).
-
- Each issue of the digest contains one or more sets of articles (called
- threads), with each set corresponding to a 'discussion' of a particular
- subject. The articles are not edited; all articles included in this digest
- are in their original posted form (as received by our news server at
- nef.ens.fr). Article threads are not added to the digest until the last
- article added to the thread is at least two weeks old (this is to ensure that
- the thread is dead before adding it to the digest). Article threads that
- consist of only one message are generally not included in the digest.
-
- The digest is officially distributed by two means, by email and ftp.
-
- If you want to receive the digest by mail, send email to listserv@ens.fr
- with no subject and one of the following commands as body:
- help Sends you a summary of commands
- subscribe csmp-digest Your Name Adds you to the mailing list
- signoff csmp-digest Removes you from the list
- Once you have subscribed, you will automatically receive each new
- issue as it is created.
-
- The official ftp info is ftp://ftp.dartmouth.edu/pub/csmp-digest.
- Questions related to the ftp site should be directed to
- scott.silver@dartmouth.edu.
-
- -------------------------------------------------------
-
- >From Rich <4thought@world.std.com>
- Subject: "Apple's 3-D interface guidelines" ??
- Date: Mon, 19 Feb 1996 00:47:38 GMT
- Organization: The World @ Software Tool & Die
-
- I recently read a review of a 3D modeling product where the
- reviewer recommended that the product's company "take to
- heart Apple's 3-D interface guidelines"...
-
- Does anyone know what particular document the reviewer was
- talking about, and how I can get my hands on it if it exists?
-
- Thanks,
- Rich Wagner
-
-
- P.S. No, I don't work for that product's company.
-
- +++++++++++++++++++++++++++
-
- >From matthewm@cts.com (matthew malevloent)
- Date: Sun, 18 Feb 1996 20:27:23 -0800
- Organization: CTS Network Services
-
- In article <3127C8AA.25E8@world.std.com>, Rich <4thought@world.std.com> wrote:
-
- > I recently read a review of a 3D modeling product where the
- > reviewer recommended that the product's company "take to
- > heart Apple's 3-D interface guidelines"...
- >
- > Does anyone know what particular document the reviewer was
- > talking about, and how I can get my hands on it if it exists?
- >
- > Thanks,
- > Rich Wagner
- >
- >
- > P.S. No, I don't work for that product's company.
-
- I would try the Apple Programmers Developers Association,
- apda@appleline.com [I think].
-
- Matthew Malevolent
-
- +++++++++++++++++++++++++++
-
- >From gurgle@apple.com (Pete Gontier)
- Date: Mon, 19 Feb 1996 13:00:32 -0800
- Organization: Apple Computer, Inc.
-
- In article <3127C8AA.25E8@world.std.com>,
- Rich <4thought@world.std.com> wrote:
-
- > I recently read a review of a 3D modeling product where the
- > reviewer recommended that the product's company "take to
- > heart Apple's 3-D interface guidelines"...
- >
- > Does anyone know what particular document the reviewer was
- > talking about, and how I can get my hands on it if it exists?
-
- In general...
-
- <http://dev.info.apple.com/insidemac/quickdraw3d>
-
- ...and in particular...
-
- <http://dev.info.apple.com/insidemac/quickdraw3d/Intro-2.html#HEADING2-17>
-
- - -
-
- Pete Gontier, Integer Poet, Apple Macintosh Developer Technical Support
-
- work mail <mailto:gurgle@apple.com>
- personal mail <mailto:gurgle@ccnet.com>
- personal web <http://www.ccnet.com/~gurgle>
- work web <http://dev.info.apple.com/dts.html>
-
- +++++++++++++++++++++++++++
-
- >From S Purcell <spurcell@shore.intercom.net>
- Date: 20 Feb 1996 01:23:22 GMT
- Organization: Soliton Software
-
- In article <3127C8AA.25E8@world.std.com>, Rich <4thought@world.std.com> wrote:
-
- > I recently read a review of a 3D modeling product where the
- > reviewer recommended that the product's company "take to
- > heart Apple's 3-D interface guidelines"...
- >
- > Does anyone know what particular document the reviewer was
- > talking about, and how I can get my hands on it if it exists?
-
- I believe they're referring to the article "Working in the 3rd Dimension"
- in issue 15 of develop. You can get it at
-
- "http://www.info.apple.com/cgi-bin/lister-pl?Apple.Support.Area/Developer_Servi
- ces/Periodicals/develop/develop15/develop_Issue_15_"
-
- it's in the Adobe portable document format. If you don't have the reader, you
- can get it at
-
- "http://www.adobe.com/Software/Acrobat/mac.html"
-
- Seth Purcell, Mac C++ Programmer for Soliton Software
-
-
-
- +++++++++++++++++++++++++++
-
- >From ur@muc.de (Uli Rueckert)
- Date: 21 Feb 1996 20:48:48 GMT
- Organization: private
-
- Hi!
-
- In article <3127C8AA.25E8@world.std.com>, Rich <4thought@world.std.com> wrote:
- > I recently read a review of a 3D modeling product where the
- > reviewer recommended that the product's company "take to
- > heart Apple's 3-D interface guidelines"...
- >
- > Does anyone know what particular document the reviewer was
- > talking about, and how I can get my hands on it if it exists?
- A preliminary version of the "QD 3D UI Guidelines" is on the cd, which is
- contained in Apple's official QD3D documentation "3D Graphics Programming
- With QD3D".
- Maybe you'll find the guidelines on the QD3D SDK, which is available at
- <ftp://ftp.info.apple.com/Apple.Support.Area/QuickDraw3D/>.
-
- cu,
- U. Rueckert
-
- +++++++++++++++++++++++++++
-
- >From Rich <4thought@world.std.com>
- Date: Sat, 24 Feb 1996 18:21:49 GMT
- Organization: The World @ Software Tool & Die
-
- Uli Rueckert wrote:
- >
- > Hi!
- >
- > A preliminary version of the "QD 3D UI Guidelines" is on the cd, which is
- > contained in Apple's official QD3D documentation "3D Graphics Programming
- > With QD3D".
- > Maybe you'll find the guidelines on the QD3D SDK, which is available at
- > <ftp://ftp.info.apple.com/Apple.Support.Area/QuickDraw3D/>.
- >
- > cu,
- > U. Rueckert
-
-
- I just wanted to thank all those who responded. It turns out that
- Uli Rueckert's response gave me what I was looking for: I actually
- already had the QD-3D CD-ROM, but I hadn't found the article until
- it was pointed out to me. (Those CDs sure to pack a lot...)
-
- The other responses were also useful, though. For example, though the
- "Working in the Third Dimension" article wasn't what I was initially
- looking for, I'm glad to have gotten that (it was Email-ed to me! Talk
- about service :-)
-
- Thanks very much,
- Rich Wagner
-
-
-
- It's no big thing, It's a small thing:
- What people think
-
- -- Byrne & Eno
-
- ---------------------------
-
- >From John Moe <jmoe@wshs.luminet.net>
- Subject: 'sysz' resources
- Date: Thu, 22 Feb 1996 08:29:41 -0600
- Organization: Sundstrand Aerospace
-
- what is the 'sysz' resource? I found it in several INIT's.
- Is this related to disabling the shift key no extensions thing?
- --John
-
- +++++++++++++++++++++++++++
-
- >From david_rehring@gdt.com (David Rehring)
- Date: Thu, 22 Feb 1996 15:29:11 -0700
- Organization: GDT Softworks, Inc.
-
- In article <312C7DD5.452E@wshs.luminet.net>, John Moe
- <jmoe@wshs.luminet.net> wrote:
-
- > what is the 'sysz' resource? I found it in several INIT's.
- > Is this related to disabling the shift key no extensions thing?
- > --John
-
- John,
-
- No. It is used by the system to expand the system heap by whatever amount
- is in the first 4 bytes of the 'sysz' resource. For example, if your INIT
- loads a 10K code resource and allocates a 50K buffer in the System Heap
- (via NewPtrSys or something like it), then you would set the 'sysz'
- resource to something like 65000 (in hex).
-
- --
- David Rehring
- Software Engineer
- GDT Softworks, Inc.
- And all around wacky guy!
-
- +++++++++++++++++++++++++++
-
- >From Patrick.Stadelmann@etudiants.unine.ch (Patrick Stadelmann)
- Date: Fri, 23 Feb 1996 10:16:40 +0100
- Organization: University of Neuchatel
-
- In article <312C7DD5.452E@wshs.luminet.net>, John Moe
- <jmoe@wshs.luminet.net> wrote:
-
- > what is the 'sysz' resource? I found it in several INIT's.
- > Is this related to disabling the shift key no extensions thing?
-
- No. 'sysz' is for "system zone". This resource specify the amount
- of system heap (memory) that the INIT needs.
-
- Patrick
-
- --
- Patrick Stadelmann <Patrick.Stadelmann@etudiants.unine.ch>
-
- ---------------------------
-
- >From kvictor@best.com (Ken Victor)
- Subject: (Q) How to find local hard disk volumes only
- Date: Tue, 20 Feb 1996 15:29:05 -0800
- Organization: Victor Consultin
-
- using PBHGetVInfoSync i am able to find all mounted disks and i can
- eliminate cd-roms (as being hardware protected - bit 7 of ioVAtrb),
- foreign volumes (non zero ioVFSID), and ejected/dismounted volumes
- (ioVDrvInfo <= 0).
-
- i would also like to eliminate all floppies and ram disks. is there an
- accepted way to do this? i could eliminate floppies based on size less
- than 1.5MB, but is this the best way? i'm not sure how to eliminate ram
- disks (although at least with apple's system 7.5.2 ram disk, bit 10 of
- ioVAtrb seems to be set...)
-
- thanx,
- ken victor
-
- ps. if possible, please respond via email:
- KVictor@Best.Com
-
- +++++++++++++++++++++++++++
-
- >From mclow@mailhost2.csusm.edu (Marshall Clow)
- Date: Tue, 20 Feb 1996 21:48:40 -0800
- Organization: Aladdin Systems
-
- In article <kvictor-2002961529050001@kvictor.vip.best.com>,
- kvictor@best.com (Ken Victor) wrote:
-
- >using PBHGetVInfoSync i am able to find all mounted disks and i can
- >eliminate cd-roms (as being hardware protected - bit 7 of ioVAtrb),
- >foreign volumes (non zero ioVFSID), and ejected/dismounted volumes
- >(ioVDrvInfo <= 0).
- >
- >i would also like to eliminate all floppies and ram disks. is there an
- >accepted way to do this? i could eliminate floppies based on size less
- >than 1.5MB, but is this the best way? i'm not sure how to eliminate ram
- >disks (although at least with apple's system 7.5.2 ram disk, bit 10 of
- >ioVAtrb seems to be set...)
- >
- What do you want to do about Zip drives?
- All Apple floppy drives use the ".Sony" driver.
- So does the HD 20, if you care :-)
-
- You could check the driver reference number to see if it's a SCSI device...
-
- What, exactly are you trying to accomplish?
-
- --
- Marshall Clow
- Aladdin Systems
-
- "They that can give up essential liberty to obtain a little temporary
- safety deserve neither liberty nor safety." -- Benjamin Franklin
- _Historical Review of Pennsylvania_, 1759
-
- +++++++++++++++++++++++++++
-
- >From kvictor@best.com (Ken Victor)
- Date: Wed, 21 Feb 1996 08:53:33 -0800
- Organization: Victor Consultin
-
- In article <mclow-2002962148400001@burns.idio.com>,
- mclow@mailhost2.csusm.edu (Marshall Clow) wrote:
-
- >In article <kvictor-2002961529050001@kvictor.vip.best.com>,
- >kvictor@best.com (Ken Victor) wrote:
- >
- >>using PBHGetVInfoSync i am able to find all mounted disks and i can
- >>eliminate cd-roms (as being hardware protected - bit 7 of ioVAtrb),
- >>foreign volumes (non zero ioVFSID), and ejected/dismounted volumes
- >>(ioVDrvInfo <= 0).
- >>
- >>i would also like to eliminate all floppies and ram disks. is there an
- >>accepted way to do this? i could eliminate floppies based on size less
- >>than 1.5MB, but is this the best way? i'm not sure how to eliminate ram
- >>disks (although at least with apple's system 7.5.2 ram disk, bit 10 of
- >>ioVAtrb seems to be set...)
- >>
- >What do you want to do about Zip drives?
- >All Apple floppy drives use the ".Sony" driver.
- > So does the HD 20, if you care :-)
- >
- >You could check the driver reference number to see if it's a SCSI device...
- >
- >What, exactly are you trying to accomplish?
-
- thanx for the reply. i'm looking for all files of certain types on local
- hard disks (sorry i can't say anymore at this time).
-
- ken
-
- +++++++++++++++++++++++++++
-
- >From Jeff Pritchard <jeffp@inow.com>
- Date: Wed, 21 Feb 1996 18:50:32 -0700
- Organization: NSI/INOW
-
- Try this:
-
- Boolean VolumeIsRamDisk(short vrefnum)
- {
- short drivenum = GetDriveNum(vrefnum);
-
- QHdrPtr driveQH = GetDrvQHdr();
- DrvQElPtr driveQ = DrvQElPtr(driveQH->qHead);
- DCtlHandle theDCE;
-
- while(driveQ)
- {
- if(driveQ->dQDrive == drivenum)
- {
- short refNum = driveQ->dQRefNum;
- theDCE = GetDCtlEntry(refNum);
- Ptr theDriver = (*theDCE)->dCtlDriver;
- unsigned char *theName = (unsigned char *)((struct DRVRHeader
- *)theDriver)->drvrName;
- if(EqualString(theName,"\p.EDisk",false,false))
- return true;
- else
- return false;
- }
- driveQ = DrvQElPtr(driveQ->qLink);
- }
- return false;
- }
-
- short GetDriveNum(short vRefNum)
- {
- OSErr error;
- HParamBlockRec pb;
- unsigned char name[32];
- name[0] = 0;
-
- pb.volumeParam.ioCompletion = nil;
- pb.volumeParam.ioVolIndex = 0;
- pb.volumeParam.ioNamePtr = name;
- pb.volumeParam.ioVRefNum = vRefNum;
- error = PBHGetVInfoSync(&pb);
- if(error) return 0;
-
- return pb.volumeParam.ioVDrvInfo; // stupid name for a drive number!
- }
-
-
- BTW: I use the size to detect floppies. If anybody creates a 1.5M
- volume on a hard disk, they deserve what they get. 8^)
-
- --
- ++++++++++++++++++++++++++++++++++++++++++++++++++++
- +
- + Jeff Pritchard
- + Fremont, CA USA (SF Bay Area)
- +
- + Excessive moderation may lead to insufficiency.
- +
- ++++++++++++++++++++++++++++++++++++++++++++++++++++
-
- +++++++++++++++++++++++++++
-
- >From gurgle@apple.com (Pete Gontier)
- Date: Fri, 23 Feb 1996 12:07:44 -0800
- Organization: Apple Computer, Inc.
-
- In article <kvictor-2002961529050001@kvictor.vip.best.com>,
- kvictor@best.com (Ken Victor) wrote:
-
- > i would ... like to eliminate all floppies and ram disks. is there an
- > accepted way to do this?
-
- Not really. There are bazillions of third-party disk drivers out there,
- and just about all of them have some unique property which invalidates any
- one test. The best you can do is describe as many things about the volumes
- you want to eliminate and write a test for each of those things.
-
- > i could eliminate floppies based on size less
- > than 1.5MB, but is this the best way?
-
- This is basically what Finder does. Horrifying, eh?
-
- - -
-
- Pete Gontier, Integer Poet, Apple Macintosh Developer Technical Support
-
- work mail <mailto:gurgle@apple.com>
- personal mail <mailto:gurgle@ccnet.com>
- personal web <http://www.ccnet.com/~gurgle>
- work web <http://dev.info.apple.com/dts.html>
-
- +++++++++++++++++++++++++++
-
- >From gurgle@apple.com (Pete Gontier)
- Date: Fri, 23 Feb 1996 12:08:55 -0800
- Organization: Apple Computer, Inc.
-
- In article <312BCBE8.56C7@inow.com>, jeffp@inow.com wrote:
-
- > if(EqualString(theName,"\p.EDisk",false,false))
-
- This will find Apple's RAM disk driver, but there are lots of other RAM
- disks out there.
-
- - -
-
- Pete Gontier, Integer Poet, Apple Macintosh Developer Technical Support
-
- work mail <mailto:gurgle@apple.com>
- personal mail <mailto:gurgle@ccnet.com>
- personal web <http://www.ccnet.com/~gurgle>
- work web <http://dev.info.apple.com/dts.html>
-
- ---------------------------
-
- >From agrignon@blue.weeg.uiowa.edu (A. Grignon)
- Subject: AppleEvents to-from an extension?
- Date: 23 Feb 96 02:18:09 GMT
- Organization: University of Iowa, Iowa City, IA, USA
-
-
- I'd like to be able to send/receive apple events from an extension.
- Sending them has proven to be no problem, but how might one
- receive an AppleEvent, without having any sort of event loop? If
- I register a handler for a particular type of event, will it just
- eventually get called when nobody else will accept the event regardless?
-
- I can see a way to hack it work, by writing a jgne filter and peeking
- at everything, but this doesn't seem to be a very elegant solution.
- Surely this has been addressed by someone already?
-
- Thanks for your help,
- -Andy
-
-
-
- +++++++++++++++++++++++++++
-
- >From jonpugh@netcom.com (Jon Pugh)
- Date: Sun, 25 Feb 1996 07:43:31 GMT
- Organization: Apple Computer
-
- In article <agrignon.825041889@blue.weeg.uiowa.edu>,
- agrignon@blue.weeg.uiowa.edu (A. Grignon) wrote:
-
- >I'd like to be able to send/receive apple events from an extension.
- >Sending them has proven to be no problem, but how might one
- >receive an AppleEvent, without having any sort of event loop? If
- >I register a handler for a particular type of event, will it just
- >eventually get called when nobody else will accept the event regardless?
- >
- >I can see a way to hack it work, by writing a jgne filter and peeking
- >at everything, but this doesn't seem to be a very elegant solution.
- >Surely this has been addressed by someone already?
-
- CK Haun wrote a sample which should be in the snippets on the Apple web server.
-
- http://dev.info.apple.com/source/index.html
-
- It implements a cdev which sends AE. I don't recall if it receives them,
- but I think it does. Knowing CK, he would do a decent job of it.
-
- The simple solution is to write an application instead of a cdev. The
- Desktop Patterns cdev is really an app. It's also scriptable. It makes
- the whoe thing simple.
-
- Jon
-
- --
- What are YOU doing to oppose the Microsoft juggernaut?
- http://www.infoworkshop.com/~jonpugh/
-
- ---------------------------
-
- >From blevitt@camis.stanford.edu (Ben Levitt)
- Subject: Control panel code?
- Date: Thu, 22 Feb 1996 16:23:49 -0800
- Organization: Stanford University
-
- Could someone send me, or point me towards the C/C++ source of some simple
- control panels. I would really find some examples handy, since I'm trying
- to learn how to create one myself.
-
- Thanks!
-
- - Ben
- blevitt@CAMIS.Stanford.edu
-
- +++++++++++++++++++++++++++
-
- >From chewey@EnTechnology.com (Matthew E. Axsom)
- Date: Fri, 23 Feb 1996 15:33:19 GMT
- Organization: En Technology Corp.
-
- In article <blevitt-2202961623490001@tip-mp7-ncs-14.stanford.edu>,
- blevitt@camis.stanford.edu (Ben Levitt) wrote:
-
- >Could someone send me, or point me towards the C/C++ source of some simple
- >control panels. I would really find some examples handy, since I'm trying
- >to learn how to create one myself.
- >
- > Thanks!
- >
- > - Ben
- >blevitt@CAMIS.Stanford.edu
-
- Try this url...
-
- <ftp://mirror.apple.com//mirrors/Info-Mac.Archive/dev/src/
- cw-cdev-framework-111-cpp.hqx>
-
- -Chewey
- Matthew E. Axsom En Technology Corp.
- chewey@EnTechnology.com Macintosh Software Craftsperson
- +--------------------------------------------------------------------------+
- ->>(Speaking for myself and *not* En Technology, I submit the following)<<-
- "When you are in it up to your ears, keep your mouth shut."
-
- ---------------------------
-
- >From Jeff Walker <jwalker@chattanooga.net>
- Subject: DDP Listener Broadcast Problem
- Date: 21 Feb 1996 00:38:00 GMT
- Organization: Ultimate Technographics Inc
-
-
- I am experiencing a problem with the Multi-Node feature of AppleTalk:
-
- When my listener receives any BROADCAST packet from a process
- running on the same machine, the packet length value is bogus.
-
- Upon entry to my listener code:
-
- ( The low word of D1 is supposed to be the length to read )
- The D1 register is 0x000D0000 ( the low word being the length )
-
- The D1 register is supposed to be 0x0000XXXX ( xxxx being short
- length )
-
-
- The socket listener for a MultiNode is ( to my knowledge )
- exactly like a standard DDP Listener, except that it is always passed an
- extended header and receives Broadcasts.
-
- The listener works correctly for broadcasts from other machines
- and targeted packets from the same machine.
-
- I've read everyhing that I can get my hands on :
- Tech notes
- Inside mac networking
- inside appletalk
- and a copius amount of experimentation.
-
- Everything is by the book. Somebody please help!
-
- Sometimes I hate the macintosh
- Jeff
-
- +++++++++++++++++++++++++++
-
- >From hueras@tiac.net (Jon Hueras)
- Date: Mon, 26 Feb 1996 09:12:56 -0500
- Organization: The Internet Access Company
-
- In article <4gdph8$h3h@news.chattanooga.net>, Jeff Walker
- <jwalker@chattanooga.net> wrote:
-
- > I am experiencing a problem with the Multi-Node feature of AppleTalk:
- >
- > When my listener receives any BROADCAST packet from a process
- > running on the same machine, the packet length value is bogus.
- >
- > Upon entry to my listener code:
- >
- > ( The low word of D1 is supposed to be the length to read )
- > The D1 register is 0x000D0000 ( the low word being the length )
- >
- > The D1 register is supposed to be 0x0000XXXX ( xxxx being short
- > length )
- >
- >
- > The socket listener for a MultiNode is ( to my knowledge )
- > exactly like a standard DDP Listener, except that it is always passed an
- > extended header and receives Broadcasts.
- >
- > The listener works correctly for broadcasts from other machines
- > and targeted packets from the same machine.
- >
- > I've read everyhing that I can get my hands on :
- > Tech notes
- > Inside mac networking
- > inside appletalk
- > and a copius amount of experimentation.
- >
- > Everything is by the book. Somebody please help!
- >
- > Sometimes I hate the macintosh
- > Jeff
-
- I reported this bug to Apple almost 4 years ago. Can it really still be
- unfixed? Do you happen to know what version of AppleTalk this is happening
- on for you?
-
- In any case, here's a copy of my original bug report, complete with the
- code I came up with to work around the bug:
-
- While working on an application that makes use of AppleTalk v57's "multiple
- node architecture" I encountered what is, I believe, a bug.
-
- Whenever a packet is broadcast from the local machine, whether via a
- NetWrite call or via a writeDDP call from the "user node", the multinode
- receiver routine gets called with an incorrect value in D1 (always zero, I
- think). If a broadcast packet comes in from an external network, D1 always
- contains the number of bytes remaining to be received from packet, as
- expected.
-
- My workaround involves reconstructing the correct value for D1 using the
- packet length in the RHA and the count of the number of bytes already in
- the RHA derived from A3:
-
- move.l a3, d2 ;how many bytes in RHA?
- sub.l a2, d2
- subq.l #toRHA, d2
- cmp.l #lapHdSz+ddpLength+2, d2 ;big enough?
- blo.s FlushPkt ;no -->
- cmp.l #lapHdSz+ddphSzLong+ddpMaxData, d2 ;too big?
- bhi.s FlushPkt ;yes -->
- move.w toRHA+lapHdSz+ddpLength(a2), d0 ;does d1 agree with
- and.w #ddpLenMask, d0 ;packet length?
- subq.w #2, d0 ;(Apple bug filter)
- cmp.w d0, d1
- beq.s LengthOK ;yes -->
- cmp.b #$FF, toRHA+lapDstAdr(a2) ;broadcast pkt?
- bne.s FlushPkt ;no --> inexcusable error!
- move.w d0, d1 ;yes, fix up byte count
-
- I did get an acknowedgement of this bug report from DTS as follows:
-
- ...just received word from AppleTalk engineering that the scenario which
- you've reported is a "likely" problem, one which they will investigate
- fixing in the next revision of AppleTalk. The engineer commented that
- your solution is the "right" thing to do in the meantime.
-
- Perhaps the bug was fixed and any attempt to document it swept under the
- rug. If the bug persists in recent AppleTalk versions, though, that's
- scary.
-
- Jon
-
- +++++++++++++++++++++++++++
-
- >From hueras@tiac.net (Jon Hueras)
- Date: Mon, 26 Feb 1996 09:51:51 -0500
- Organization: The Internet Access Company
-
- After I sent the preceding followup, I scanned a directory of all my
- Developer's CD for the work Multinode and discovered a *new* addition to
- Inside Mac (first appreared on the 9/95 CD) - Networking: Multinode
- Architecture. Within, I discovered the following paragraphs:
-
- A multinode receive routine is similar in concept to a socket listener that
- receives packets addressed to a specific socket. The chapter “Datagram
- Delivery Protocol (DDP)” in this book includes a sample socket listener. To
- create a receive routine, perform the following steps:
-
- 1. [...]
-
- 2. Determine the number of bytes that have already been read into the .MPP
- driver’s internal buffer, called the RHA.
-
- To do this, subtract the beginning address of the read-header area (RHA)
- from the value in register A3, which points past the last byte read into
- the RHA. To locate the offset at the beginning of the RHA, you can use
- the toRHA equate.
-
- Although this doesn't explicitly warn you *not* to trust D1, if you follow
- their instructions you'll be doing what my workaround does.
-
- Checking back, I see that the Tech Note "NW 13 - AppleTalk: The Rest of
- the Story" says basically the same thing, so I guess there was a doc "fix"
- after all. Don't know why they couldn't fix AppleTalk itself; they must
- have desperately needed D1 for something else... :-)
-
- Jon
-
- ---------------------------
-
- >From chrisman@ucdmath.ucdavis.edu (Mark Chrisman)
- Subject: Is C++ OK? Make yourself heard!
- Date: 14 Feb 1996 12:00:54 GMT
- Organization: Dept. of Computer & Information Science, NCTU, Taiwan
-
- For my game, I'm working on some modules that I intend to be re-usable
- tools for other game programmers (that's you!).
-
- I'm planning an object-oriented approach, using C++. My question is
- this: How many of you would not consider using a tool if it's in C++?
- (To use the tools, you would need to know C++, because you would have to
- define some subclasses.)
-
- Objections based on the computational overhead of OOP don't count. Speed
- is not an issue here, because the code is for things (e.g. preference
- files) which won't be part of a real-time game loop.
-
- -Mark
-
- +++++++++++++++++++++++++++
-
- >From jregier@qualcomm.com (Jason Regier)
- Date: Wed, 14 Feb 1996 09:43:24 -0800
- Organization: Qualcomm, Inc.
-
- In article <chrisman-1402960404220001@ppp059.inreach.com>,
- chrisman@ucdmath.ucdavis.edu (Mark Chrisman) wrote:
-
- > How many of you would not consider using a tool if it's in C++?
-
- If this is an application, the language in which you coded it should be
- transparent to me or any other user. I want to know that it always does
- the job right, and if possible, does it in a quick and easy fashion.
-
- But if you're thinking of supplying your own game architecture or code
- snippets for other programmers, that's another story. I'd say C++ is a
- great vehicle for reusable code. IMHO, object oriented languages allow
- you to more easily maintain and upgrade an existing code base. There is a
- speed and possible memory hit from the object oriented approach, and it
- can be substantial if you don't know what you're doing. But if you code
- well in C++, you should be able to emerge with some really nice code which
- is also easy to upgrade and maintain.
-
- Of course, haters of C++ will tell you this is also possible in a
- procedure- based language like C or Pascal. They'll also remind you that
- C++ gives you more than enough rope to hang yourself. But it's your call!
-
- Jason
-
- --
- Jason Regier
- GlobalStar Software Engineer
- QUALCOMM, Inc.
- (619) 658-4752
- jregier@qualcomm.com
-
- +++++++++++++++++++++++++++
-
- >From chrisman@ucdmath.ucdavis.edu (Mark Chrisman)
- Date: 14 Feb 1996 22:25:12 GMT
- Organization: Dept. of Computer & Information Science, NCTU, Taiwan
-
- In article <jregier-1402960943240001@jregier-mac.qualcomm.com>,
- jregier@qualcomm.com (Jason Regier) wrote:
-
- |In article <chrisman-1402960404220001@ppp059.inreach.com>,
- |chrisman@ucdmath.ucdavis.edu (Mark Chrisman) wrote:
- |
- |> How many of you would not consider using a tool if it's in C++?
- |
- |if you're thinking of supplying your own game architecture or code
- |snippets for other programmers... I'd say C++ is a
- |great vehicle for reusable code. IMHO, object oriented languages allow
- |you to more easily maintain and upgrade an existing code base. There is a
- |speed and possible memory hit from the object oriented approach, and it
- |can be substantial if you don't know what you're doing.
-
- While we're at it, I wonder if someone could say a few words about the
- speed & memory hit from using C++. I can see that there is a *small* (how
- small?) overhead in having to look up address of virtual functions. And I
- can see that memory fragmentation might become a problem since C++ objects
- are pointers, not handles. Are there other drawbacks? What advice would
- you give to someone to wants to "know what they're doing"?
-
- |But if you code
- |well in C++, you should be able to emerge with some really nice code which
- |is also easy to upgrade and maintain.
- |
- |Of course, haters of C++ will tell you this is also possible in a
- |procedure- based language like C or Pascal. They'll also remind you that
- |C++ gives you more than enough rope to hang yourself. But it's your call!
-
- Well, yes, *I* am quite convinced that using C++ is a great idea. My
- concern is really this: How many of these C++ haters are there? Will my
- neat tools go unused just because I decided to use C++?
-
- (If they go unused because they're no good...well, that's another issue :-)
-
- -Mark
-
- +++++++++++++++++++++++++++
-
- >From kbs3387@silver.sdsmt.edu (Kevin Stone)
- Date: 14 Feb 1996 21:06:37 GMT
- Organization: South Dakota School of Mines and Technology
-
- : For my game, I'm working on some modules that I intend to be re-usable
- : tools for other game programmers (that's you!).
- :
- : I'm planning an object-oriented approach, using C++. My question is
- : this: How many of you would not consider using a tool if it's in C++?
- : (To use the tools, you would need to know C++, because you would have to
- : define some subclasses.)
-
- For the sake of humanity!! Don't do it! Resist the evil forces of C++!!
-
- No... really. If you don't use virtual functions (much) and try to
- keep down on inheriting multiple classes, you should be fine.
- Undoubtably, you will see a small speed hit using C++ instead of C,
- but sometimes the good's outweigh the means.
- If speed isn't an issue for you, then I guess what I just said dosn't
- matter.
-
- : Objections based on the computational overhead of OOP don't count. Speed
- : is not an issue here, because the code is for things (e.g. preference
- : files) which won't be part of a real-time game loop.
-
- Like I said, if speed isn't an issue... it really dosn't matter.
- Personaly, I don't use C++ for several reasons (the main one is speed,
- and the lack there of).
-
- I guess what you really should be asking your self is... Do I NEED C++
- to write this library. Sometimes the answer is yes... sometimes the
- answer is no. If you think you can take advantage of things like virtual
- functions and inheritance to make the tool easier to use, then I'd say
- go for it! :)
-
- BAS
-
-
- +++++++++++++++++++++++++++
-
- >From square@phoenix.princeton.edu (Hung F. Fong)
- Date: 15 Feb 1996 03:50:05 GMT
- Organization: Princeton University
-
- In article <4ftist$81g@news.sdsmt.edu> kbs3387@silver.sdsmt.edu (Kevin Stone) writes:
- > No... really. If you don't use virtual functions (much) and try to
- > keep down on inheriting multiple classes, you should be fine.
- > Undoubtably, you will see a small speed hit using C++ instead of C,
- > but sometimes the good's outweigh the means.
- > If speed isn't an issue for you, then I guess what I just said dosn't
- > matter.
- >
- >: Objections based on the computational overhead of OOP don't count. Speed
- >: is not an issue here, because the code is for things (e.g. preference
- >: files) which won't be part of a real-time game loop.
- >
- > Like I said, if speed isn't an issue... it really dosn't matter.
- > Personaly, I don't use C++ for several reasons (the main one is speed,
- > and the lack there of).
- >
- > I guess what you really should be asking your self is... Do I NEED C++
- > to write this library. Sometimes the answer is yes... sometimes the
- > answer is no. If you think you can take advantage of things like virtual
- > functions and inheritance to make the tool easier to use, then I'd say
- > go for it! :)
- >
- >BAS
- >
-
- I disagree completely that C++ is slower than C, based on two things:
- - inlining in C++ allow you to do things where you normally would use
- function calls in C due laziness. (e.g. complex assignment statements)
- - in the case of virtual functions it's the fastest way to implement
- "polymorphism" in practice than your usual switch statement.
- When do you use a virtual function? for example, let's say in your
- game with many different kinds of draw() routines. in C without
- exploiting function pointers it should look like:
- switch(object.type) {
- case PLAYER: /*blah blah blah*/
- case BULLET1: /*blah blah blah*/
- ...
- default: /* error */
- }
- In c++? simply object->draw(); !!!
- translated to C, this operation is basically equivalent to:
- (*(object->vfuncTable[DRAW]))(object);
- with the vfuncTable correctly reflecting the type of object
- you're playing with.
-
- But then, in an inner loop, one can ALWAYS go back to procedural paradigm.
- Therefore, I see absolutely no reason to abandon C++. While it gives
- you the power to simplify complicated design structure and yet the
- flexibility to write totally C efficency equivalent code in speed critical
- portion of the program. And mind you, the latter is not a large part at all.
-
- HFF
-
- +++++++++++++++++++++++++++
-
- >From pottier@drakkar.ens.fr (Francois Pottier)
- Date: 15 Feb 1996 14:29:47 GMT
- Organization: Ecole Normale Superieure, Paris, France
-
- In article <chrisman-1402961428400001@ppp068.inreach.com>,
- Mark Chrisman <chrisman@ucdmath.ucdavis.edu> wrote:
-
- >While we're at it, I wonder if someone could say a few words about the
- >speed & memory hit from using C++. I can see that there is a *small* (how
- >small?) overhead in having to look up address of virtual functions. And I
- >can see that memory fragmentation might become a problem since C++ objects
- >are pointers, not handles.
-
- The cost of virtual function calls is ridiculously low, except maybe in
- inner game loops. I use plenty of function calls in rather time-critical
- code with no problems.
-
- As for the cost of using pointers instead of handles, well, there is a
- risk of fragmentation, but you are actually gaining a lot of speed by
- doing that.
-
- > What advice would you give to someone to wants to "know what they're
- > doing"?
-
- My advice would be to not worry too much about the language. Whatever
- language you choose, you should worry about the design of your
- API. Make it easy to understand, free of pitfalls, easily extendable,
- easily reusable, well documented, etc. Careful design can be done in C
- or C++. C++ does help you sometimes, for instance if your concepts map
- easily to a class hierarchy. It can also bite you in the ass, for
- instance if you think your concepts map to a class hierarchy and then
- later discover that the mapping is not perfect, start hacking with
- virtual base classes, etc.
-
- Try to not over-use C++ features because they're "cool". Just use the
- features which are natural for your architecture.
-
-
- --
- Francois Pottier
- Francois.Pottier@ens.fr
- Francois.Pottier@inria.fr
- http://www.eleves.ens.fr:8080/home/pottier/
-
- +++++++++++++++++++++++++++
-
- >From johnb@hk.super.net (John W. Blackburne)
- Date: Thu, 15 Feb 1996 23:01:37 +0800
- Organization: Tempest
-
- In article <chrisman-1402960404220001@ppp059.inreach.com>,
- chrisman@ucdmath.ucdavis.edu (Mark Chrisman) wrote:
-
- :For my game, I'm working on some modules that I intend to be re-usable
- :tools for other game programmers (that's you!).
- :
- :I'm planning an object-oriented approach, using C++. My question is
- :this: How many of you would not consider using a tool if it's in C++?
- :(To use the tools, you would need to know C++, because you would have to
- :define some subclasses.)
-
- At least one, me. I'm quite happy with C and have no immediate plans to
- move to C++. I may end up working with it one day, but not for games
- programs.
-
- :Objections based on the computational overhead of OOP don't count. Speed
- :is not an issue here, because the code is for things (e.g. preference
- :files) which won't be part of a real-time game loop.
- :
- :-Mark
-
- John
- --
- John Blackburne, johnb@tempest.net.hk
- Programmer Asia, Inc. Online: http://www.asia-inc.com
- Technology consultant and trainer: http://www.hk.super.net/~johnb
-
- +++++++++++++++++++++++++++
-
- >From bwade@qualia.com (Bretton Wade)
- Date: Thu, 15 Feb 1996 11:28:27 -0500
- Organization: qualia, inc.
-
- I also disagree about the speed issue. In general, the biggest speed
- problems come from poor design, and OOP is a significantly better design
- tool than sequential programming.
-
- --
- bwade@qualia.com
- http://www.qualia.com/
-
- +++++++++++++++++++++++++++
-
- >From dbshapco@bnr.ca (Brad Shapcott)
- Date: 15 Feb 1996 20:04:22 GMT
- Organization: Bell-Northern Research Ltd.
-
- In article <bwade-1502961128270001@frost.qualia.com>,
- Bretton Wade <bwade@qualia.com> wrote:
- >I also disagree about the speed issue. In general, the biggest speed
- >problems come from poor design, and OOP is a significantly better design
- >tool than sequential programming.
-
- An apocryphal story from a friend recounts a defense of direct system calls
- into the Amiga OS from a group of amateur programmers, because they were
- necessary for speed, despite the fact that Commodore advised against them
- and would not guarantee compatability between OS releases. (And predicatably,
- the programs broke horribly across OS releases, meaning more hacks into the
- code to fix compatability.)
-
- Another programmer, presumably more professional, took the source for the
- code in question and reprogrammed it using the documented OS calls and better
- programming techniques. The execution speed ended up faster. The problem,
- so it goes, lies not in the language choice, but in the programmer (in 90% of
- cases).
-
- Many beginning or ad hoc programmers develop a bad habit of using questionable
- optimizations, whereas a bit of education in design, ADTs and execution
- efficiency go a lot longer towards tight code that not only executes faster,
- but is easier to maintain and upgrade. I'm always suspicious when people
- complain that they are being kept too far away from the machine, or don't
- know why bubble sorts are bad, or don't comprehend the implications of
- Turing Machine Equivalence.
-
- C++ is a perfectly good language for such things.
-
-
- Brad Shapcott
-
- +++++++++++++++++++++++++++
-
- >From zinger@cloudnet.com (Chris S. Dillman)
- Date: 15 Feb 1996 21:40:54 GMT
- Organization: Cloudnet, St. Cloud MN (612)-240-8259 login as guest
-
-
- CW C++ SPEED HIT.
-
- Ok I wrote Death from above in mostly CW C++.
- At first it was barley playable on 68K.
- But after some intense optimizations.
- I got it to be nice a playable on a 25Mhz 040
- Full screen Pixel Doubled and 32 channel music.
-
- Even plays on a 20Mhz 040 for for megs ram and ramdoubler with music on.
-
- any now C++ is great.
- Speed it is minimal Unless you implement a VECTOR LIB Then the math is
- WAY way way slower.
-
- Some guy on AOL did a comparision on that.
-
- Any how I use lots of virtual FN in all my sprite code.
- So whats the problem with useing virtual functions a lot???
- Anyone???
-
- (Im not a C++ Guru)
-
-
-
- +++++++++++++++++++++++++++
-
- >From asouthwick@vnet.ibm.com (Andrew R. Southwick)
- Date: 15 Feb 1996 22:05:18 GMT
- Organization: ISSC
-
- I vote for C++. If the library is useful, I want it. If your library has
- a clean, mix-in architecture, I can use it straight. A note on source vs.
- linkable libraries: if your architecture and library interface isn't clean,
- using it is a pain in the ass. I can read your source code, figure out the
- underlying mechanisms, completely rewrite the functionality, and integrate
- it seamlessly with my existing project FASTER than trying to use a poorly-
- written, confusing, buggy, and needlessly complex library. I've got so
- much of my own framework written and working already that trying to adhere
- to someone else's poor idea of an OO framework is trouble I don't want.
-
- pottier@drakkar.ens.fr (Francois Pottier) writes:
- >The cost of virtual function calls is ridiculously low, except maybe in
- >inner game loops. I use plenty of function calls in rather time-critical
- >code with no problems.
-
- Depends on how many times your "inner loop" is called. 186,000 function
- calls per frame is devastatingly slow, whether its direct dispatch or
- virtual-function. For time-critical, tight, and insanely popular (i.e.
- frequently called) inner-inner-loops, NO function calls is the best
- choice. Also check your cache size: if your inner loops are larger than
- the code cache size, recode. My 5DOF engine looped, 320 times, through
- code that was just slightly larger than the 4K cache on the 040. I
- rewrote it to concentrate in different areas (best case, it blows the
- cache once for each frame generated, average case was around 20 or so
- with the map I was using).
-
- Optimizing code for games is really an assembly and compiler-technology
- process, and is independent of the language you are using. To do things
- fast, you need to know more about your tools than the simple facts of
- what operator-overloading is, etc.
-
- >> What advice would you give to someone to wants to "know what they're
- >> doing"?
-
- Learn about compiler technology. Get a book on it, plus an assembly
- language manual (if you don't know ASM yet). Ask direct questions about
- what (eg) "blowing the cache" is, how to find out if you're doing it, etc.
- Disassembly your source. Learn about register coloring. Learn general
- optimization techniques.
-
- Optimization is an entirely different issue than C vs. C++; the differences
- between these languages make only a minor impact on your performance numbers.
-
- A related issue is virtual functions in C++ vs. direct dispatch in C
- (this serves nicely as an example of many of the "slow" mechanisms in C++
- versus their fast "counterparts" in C). Virtual function calls *are*
- slower than direct dispatch, but you don't use them in C++ as a parallel
- to direct dispatch in C; they replace function pointers and switch
- statements, not function calls themselves.
-
- Summary: The "C++ is slower than C" argument is a communist plot. Using
- C++ correctly is an easy task, but you have to think in C++, which does
- take a lot of effort to learn how to do. Further, optimizing code is
- an almost entirely separate matter.
-
-
- Andrew R Southwick -={C++/OO Programmer}=- asouthwick@vnet.ibm.com
- #include <stddisclaimer.h> I speak not for IBM.
- -= Freedom by permission is a contradiction in terms =-
-
-
- +++++++++++++++++++++++++++
-
- >From dbshapco@bnr.ca (Brad Shapcott)
- Date: 16 Feb 1996 16:31:03 GMT
- Organization: Bell-Northern Research Ltd.
-
- In article <4g0996$75v@orion.cloudnet.com>,
- Chris S. Dillman <zinger@cloudnet.com> wrote:
- >
- >Any how I use lots of virtual FN in all my sprite code.
- >So whats the problem with useing virtual functions a lot???
- >Anyone???
-
- Overhead for virtual functions is negligible. Pushing a large parameter list
- on the stack would be much more costly. Another thing to be suspicious of:
- programmers who are afraid of virtuals functions because of performance costs.
-
-
- Brad Shapcott
-
- +++++++++++++++++++++++++++
-
- >From jmunkki@beta.hut.fi (Juri Munkki)
- Date: 17 Feb 1996 18:27:10 GMT
- Organization: Helsinki University of Technology
-
- In article <4g2bg7$cr0@bmerhc5e.bnr.ca> dbshapco@bnr.ca (Brad Shapcott) writes:
- >In article <4g0996$75v@orion.cloudnet.com>,
- >Chris S. Dillman <zinger@cloudnet.com> wrote:
- >>Any how I use lots of virtual FN in all my sprite code.
- >>So whats the problem with useing virtual functions a lot???
- >>Anyone???
-
- >Overhead for virtual functions is negligible. Pushing a large parameter list
- >on the stack would be much more costly. Another thing to be suspicious of:
- >programmers who are afraid of virtuals functions because of performance costs.
-
- I make all methods virtual, but I still use Think C with object extensions.
- The nice thing about Think C is that it knows how to optimize monomorphic
- methods...meaning that if you only have a single instance of a virtual
- function, it becomes non-virtual at link time.
-
- I don't think any real C++ compilers know how to do that, but please correct
- me if I'm wrong. I would be delighted if Codewarrior supported it.
-
- --
- Juri Munkki jmunkki@iki.fi Life is easy when polygons are cheap.
- http://www.iki.fi/jmunkki Windsurfing: Faster than the wind.
-
- +++++++++++++++++++++++++++
-
- >From howard@sirius.com (Howard Berkey)
- Date: 17 Feb 1996 22:00:47 GMT
- Organization: Weyland-Yutani Thinking Machines Division
-
- In article <4fvg0r$4pj@nef.ens.fr>, pottier@drakkar.ens.fr (Francois
- Pottier) wrote:
- >
- > Try to not over-use C++ features because they're "cool". Just use the
- > features which are natural for your architecture.
-
- This is very good advice...
-
- Alternatively, if someone was a strong vanilla-c programmer debating
- whether or not to use C++ for a library, I'd suggest perhaps just using
- C++ as a "better C" for the first project, taking advantage of the things
- that can directly benefit a C programmer, like using inlined functions for
- effeciency, simple classes rather than structures for data types, and
- function overloading rather than varargs for simplicity in API development
- when you have several ways you want to be able to call a function. These
- things are all very cool and can directly benefit a C programmer without
- getting into C++'s more complex features like templates.
-
- -H-
-
- --
- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
- Howard Berkey, PP-ASEL, DoD #0944 howard@sirius.com
- http://www.sirius.com/~howard
-
- +++++++++++++++++++++++++++
-
- >From Thomas DeWeese <deweese@image.kodak.com>
- Date: Mon, 19 Feb 1996 10:16:43 -0500
- Organization: Eastman Kodak
-
- Mark Chrisman wrote:
- >
- > In article <jregier-1402960943240001@jregier-mac.qualcomm.com>,
- > jregier@qualcomm.com (Jason Regier) wrote:
- >
- > |In article <chrisman-1402960404220001@ppp059.inreach.com>,
- > |chrisman@ucdmath.ucdavis.edu (Mark Chrisman) wrote:
- > |
- > |IMHO, object oriented languages allow
- > |you to more easily maintain and upgrade an existing code base. There is a
- > |speed and possible memory hit from the object oriented approach, and it
- > |can be substantial if you don't know what you're doing.
- >
- > While we're at it, I wonder if someone could say a few words about the
- > speed & memory hit from using C++.
-
- > I can see that there is a *small* (how small?) overhead in having to look up
- > address of virtual functions. And I can see that memory fragmentation might
- > become a problem since C++ objects are pointers, not handles. Are there
- > other drawbacks? What advice would you give to someone to wants to
- > "know what they're doing"?
-
- The real things to look out for are not what you have listed. The
- most dangerous thing in C++ is that it tends to make you feel like you have
- more control over what is happening than you actually have. It is very
- easy for a simple looking line of code to actually be a serious speed hit.
-
- Some stuff to look out for:
- Small classes - It is very enticing to create small classes that
- 'help' you do your work (like a 2Dpoint class). The thing to watch out
- for is the hidden overhead of such classes. Depending on what the class
- contains the construction of such an object can easily balloon from 2 move
- instructions to 20-30 instructions for setting up a V-table, calling the
- constructor initializing the values and returning. This can get much worse
- if you have type converters which are constantly creating and destroying
- temporaries.
-
- Inlines that don't get inlined. While it is very nice that C++
- offers the inline declairation take it with a grain of salt (a _very_large_
- grain of salt). There are numerous cases where inlines do not get inlined,
- and worse yet those cases vary from compiler to compiler. So as an example,
- I use a set of macros that define get/set functions for data members (so I
- can have public read, protected write). I have extensively tested these
- macros to make sure that the get inlined under the majority of circumstances
- (they are pretty simple). Well I was writting some test code and I moved
- some code into inlines in the definition of the class (above my data member
- definitions). Suddenly my code ran _slower_. I checked and the moved code
- was being inlined...
- eventually I noticed that the data accessed were _not_ being inlined because
- the 'inline' functions were being used before the inline declairation. The
- compiler was completely free not to inline, and the program did the right
- thing, just _very_ slowly.
-
- Class Data Members, for what ever reason code like the following
- tends to be very poorly optomized:
-
- class iter
- {
- public:
- iter(char *start, char *end){ptr=start; endPtr=end;}
- iter &operator++(void) {ptr++; return *this}
- char get(void)const{return *ptr;}
- bool_t done(void)const {return ptr>=endPtr;}
- protected:
- char *ptr, *endPtr;
- }
-
- ...
- for (iter I(start,end);!I.done();I++)
- {...
- x = I.get();
- ... }
-
- Many compilers feel the need to load and store I.ptr at every iteration,
- as well as loading endPtr for the check. Of lesser concern many
- compilers refuse to optomize accross inline function boundries (moving
- assignments around to keep the pipeline from stalling etc).
-
- The real problem here is that if you _depend_ on the function being inlined
- for speed you have to constantly be rechecking the code to see if it is still
- being inlined because there are _lots_ of things that can code to suddenly
- stop being inlined.
-
- For this reason I have started to move away from relying on inlining, and
- using the tried and true methods of macros, and hand expansion/machine
- code generation. I don't like it but it can be a nightmare to track down
- what is being inlined and what isn't. I don't have these problems with
- these 'more traditional' methods.
-
- If you are looking for flexability and speed is secondary C++ is wonderful.
- But never underestimate the affect of an extra load/store to main memory,
- in the wrong place, on program performance.
-
- > My concern is really this: How many of these C++ haters are there? Will my
- > neat tools go unused just because I decided to use C++?
-
- For stuff like preferences most of my comments are irrelivant. If
- a person is writting his program all in pascal they won't use your stuff. If
- most of the program is C they might learn enough C++ to use your stuff (depends
- a lot on how hard your stuff is to use, ehh?).
- --
- Thomas DeWeese
- deweese@kodak.com
-
- +++++++++++++++++++++++++++
-
- >From monnet@alpes-net.fr (Nicolas Monnet)
- Date: Mon, 19 Feb 1996 23:10:09 +0100
- Organization: Ensieg/I.N.P.G.
-
- In article (Dans l'article) <3128945B.35E6@image.kodak.com>, Thomas
- DeWeese <deweese@image.kodak.com> wrote (écrivait) :
-
- > Mark Chrisman wrote:
-
- > The real things to look out for are not what you have listed. The
- > most dangerous thing in C++ is that it tends to make you feel like you have
- > more control over what is happening than you actually have. It is very
- > easy for a simple looking line of code to actually be a serious speed hit.
- >
- > Some stuff to look out for:
- > Small classes - It is very enticing to create small classes that
- > 'help' you do your work (like a 2Dpoint class). The thing to watch out
- > for is the hidden overhead of such classes. Depending on what the class
- > contains the construction of such an object can easily balloon from 2 move
- > instructions to 20-30 instructions for setting up a V-table, calling the
-
- It's easy to type "=" instead of "==", but I cannot imagine typing
- "virtual" accidentally... except if one does not know what it means!
-
- > constructor initializing the values and returning. This can get much worse
- > if you have type converters which are constantly creating and destroying
- > temporaries.
-
- One surely needs to understand perfectly object instanciation to properly
- use C++. I'm not sure I do understand all the subtleties -- but, I
- understand 68k ML and I'm always able to take a look at the code
- produced...
-
- > Inlines that don't get inlined. While it is very nice that C++
- > offers the inline declairation take it with a grain of salt (a _very_large_
- > grain of salt). There are numerous cases where inlines do not get inlined,
- > and worse yet those cases vary from compiler to compiler. So as an example,
- > I use a set of macros that define get/set functions for data members (so I
- > can have public read, protected write). I have extensively tested these
- > macros to make sure that the get inlined under the majority of circumstances
- > (they are pretty simple). Well I was writting some test code and I moved
- > some code into inlines in the definition of the class (above my data member
- > definitions). Suddenly my code ran _slower_. I checked and the moved code
- > was being inlined...
-
- Then it might be helpful that the compiler generate a report about
- inlining -- why it did'nt inline and why.
- Every compiler has its specifics; CW inlining scheme is described
- rather precisely in a note, I remember. The issue is: if one uses C++ and
- needs speed, then he needs to know those possible bottlenecks.
-
- > eventually I noticed that the data accessed were _not_ being inlined because
- > the 'inline' functions were being used before the inline declairation. The
- > compiler was completely free not to inline, and the program did the right
- > thing, just _very_ slowly.
- >
- > Class Data Members, for what ever reason code like the following
- > tends to be very poorly optomized:
- >
- > class iter
- > {
- > public:
- > iter(char *start, char *end){ptr=start; endPtr=end;}
- > iter &operator++(void) {ptr++; return *this}
- > char get(void)const{return *ptr;}
- > bool_t done(void)const {return ptr>=endPtr;}
- > protected:
- > char *ptr, *endPtr;
- > }
- >
- > ...
- > for (iter I(start,end);!I.done();I++)
- > {...
- > x = I.get();
- > ... }
- >
- > Many compilers feel the need to load and store I.ptr at every iteration,
- > as well as loading endPtr for the check. Of lesser concern many
- > compilers refuse to optomize accross inline function boundries (moving
- > assignments around to keep the pipeline from stalling etc).
- >
- > The real problem here is that if you _depend_ on the function being inlined
- > for speed you have to constantly be rechecking the code to see if it is still
- > being inlined because there are _lots_ of things that can code to suddenly
- > stop being inlined.
- >
- > For this reason I have started to move away from relying on inlining, and
- > using the tried and true methods of macros, and hand expansion/machine
- > code generation. I don't like it but it can be a nightmare to track down
- > what is being inlined and what isn't. I don't have these problems with
- > these 'more traditional' methods.
- >
- > If you are looking for flexability and speed is secondary C++ is wonderful.
- > But never underestimate the affect of an extra load/store to main memory,
- > in the wrong place, on program performance.
-
- <snip>
- > --
- > Thomas DeWeese
- > deweese@kodak.com
-
- +++++++++++++++++++++++++++
-
- >From PaulS101@mailbox.ioa.com (Paul Sexton)
- Date: Mon, 19 Feb 1996 23:55:23 -0500
- Organization: Vnet Internet Access, Charlotte, NC - info@char.vnet.net
-
- In article <jregier-1402960943240001@jregier-mac.qualcomm.com>,
- jregier@qualcomm.com (Jason Regier) wrote:
-
- > In article <chrisman-1402960404220001@ppp059.inreach.com>,
- > chrisman@ucdmath.ucdavis.edu (Mark Chrisman) wrote:
- >
- > > How many of you would not consider using a tool if it's in C++?
- >
- The main problem is that c++ libraries tend to be compiler specific, so
- you wind up supporting (at least recompiling) individually for all the
- major systems. CW has had problems with libraries breaking on each
- release.
-
- I use C++ exclusively (even on "pure" C code that doesn't need OOP) to get
- the extra features and convenience. But if I was going to put out a
- library for others to use, I'd probably use straight C.
-
- Paul
-
- --
-
- This posting was produced in a Microsoft free environment
- for your protection.
-
- +++++++++++++++++++++++++++
-
- >From jregier@qualcomm.com (Jason Regier)
- Date: Tue, 20 Feb 1996 10:24:54 -0800
- Organization: Qualcomm, Inc.
-
- In article <3128945B.35E6@image.kodak.com>, Thomas DeWeese
- <deweese@image.kodak.com> wrote:
-
- > Some stuff to look out for:
- > Small classes - It is very enticing to create small classes that
- > 'help' you do your work (like a 2Dpoint class). The thing to watch out
- > for is the hidden overhead of such classes.
- >
- Yep, this is totally true. But if you know C++ well, then you should know
- when constructors and destructors are called, and when default
- constructors and destructors are created, etc. People say this all the
- time-- C++ has a lot of flexibility, but it also has a lot of pitfalls as
- well.
-
- > Inlines that don't get inlined.
- >
- Well, I think inlining is a pretty nice feature, supported exclusively in
- C++. But like all "features", there are some pretty serious drawbacks, as
- you mentioned. Not all compilers inline all functions declared as inlined
- (especially inlined virtual functions, which very few compilers inline).
- That's the breaks, I guess, but if the compiler inlines like it should,
- you're still somewhat better off than you are in C.
-
- Ah, but then why not inline all your functions? One of the major
- drawbacks to inlining is the possible resulting code bloat, which means
- bigger application sizes. And if you're trying to optimize some code and
- you inline it, there's the possibility that the generated code won't fit
- in the cache, and you may actually degrade the performance of your code.
- It all sorta depends. Inlining is a nice option, but it's not a panacea
- to all programming problems. Like any C++ feature, use it judiciously.
-
- For anybody who's just listening in on this thread, don't be fooled into
- thinking that the above list is an extensive list of C++ pitfalls.
- There's a ton of little gotchas, and I think it's better to learn about
- them from a good C++ book instead of a news thread.
-
- Jason
-
- --
- Jason Regier
- GlobalStar Software Engineer
- QUALCOMM, Inc.
- (619) 658-4752
- jregier@qualcomm.com
-
- +++++++++++++++++++++++++++
-
- >From brian@www.tmarts.com (Brian Gray)
- Date: 23 Feb 1996 19:38:04 GMT
- Organization: TM Interactive Inc.
-
- In article <4fuahd$j52@cnn.Princeton.EDU>, square@phoenix.princeton.edu
- (Hung F. Fong) wrote:
-
- > - inlining in C++ allow you to do things where you normally would use
- > function calls in C due laziness. (e.g. complex assignment statements)
-
- Actually, when you inline a function in C++, the compiler often has the
- option of ignoring your request and refusing to inline it, treating it as
- a normal function with the standard overhead thus associated. This
- happens usually when you attempt to inline a function that is longer than
- a given amount determined by the compiler. I'd say in this respect C++
- offers inlining as a crutch that may deny you support at any minute.
- The more controlled alternative, which is also available in C, is using
- macros. Keep in mind though that when the compiler decides not to inline
- a function so defined in the code, it usually does it because the added
- memory footprint of 50 copies of a 10-line function overrides the
- importance of the gained speed. It's nice of the compiler to look out for
- my well-being, but I'd rather take responsibility for my own code.
-
- --
- Brian Gray, Multimedia Manager
- TM Interactive, Inc.
- 9696 Culver Blvd., Suite 105
- Culver City, CA 90232
- (310)837-8377 x124
-
- +++++++++++++++++++++++++++
-
- >From "Mark H. DeForest" <markd@cyan.com>
- Date: Mon, 26 Feb 1996 13:41:37 -0800
- Organization: Cyan, Inc.
-
- Brian Gray wrote:
- >
- > In article <4fuahd$j52@cnn.Princeton.EDU>, square@phoenix.princeton.edu
- > (Hung F. Fong) wrote:
- >
- > > - inlining in C++ allow you to do things where you normally would use
- > > function calls in C due laziness. (e.g. complex assignment statements)
- >
- > Actually, when you inline a function in C++, the compiler often has the
- > option of ignoring your request and refusing to inline it, treating it as
- > a normal function with the standard overhead thus associated. This
- > happens usually when you attempt to inline a function that is longer than
- > a given amount determined by the compiler. I'd say in this respect C++
- > offers inlining as a crutch that may deny you support at any minute.
-
- On a number of C++ compilers, you can control the inline function size (I
- haven't found this in CW8, though). And some C++ compilers will automatically
- turn a small function into an inline function as an optimization (kind of like
- the "register" keyword is just a suggestion to the compiler), so you may be
- getting this benefit even if your coding in C, but using a C++ compiler.
-
- > The more controlled alternative, which is also available in C, is using
- > macros.
-
- The intrusive manner of macros, not really being functions, but treated as such
- (like a multi-statement macro used in an if-statement) is one of the reasons why
- inline functions were created.
-
- > Keep in mind though that when the compiler decides not to inline
- > a function so defined in the code, it usually does it because the added
- > memory footprint of 50 copies of a 10-line function overrides the
- > importance of the gained speed. It's nice of the compiler to look out for
- > my well-being, but I'd rather take responsibility for my own code.
-
- Most optimizing compilers allow you to control this. You can pick compiler
- setting that favor speed over memory footprint. This is much easier to change
- than if you had a lot of macros and allows you to use the tool to help find the
- best fit for your situation rather than changing a lot of code.
-
-
- mark
-
- - - _ -----------------------------------------------------
- / Mark H. DeForest mailto:markd@cyan.com
- \_/ http://www.cyan.com
- C Y A N
-
- ---------------------------
-
- >From nagle@netcom.com (John Nagle)
- Subject: Removing a Gestalt entry - possible?
- Date: Tue, 20 Feb 1996 03:33:23 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
- Is there any way to remove a Gestalt entry? I'd like to do
- this when a driver gets unloaded. Resetting the Gestalt entry
- to nil seems like a bad idea. Any ideas? Thanks.
-
- John Nagle
-
- +++++++++++++++++++++++++++
-
- >From jumplong@aol.com (Jump Long)
- Date: 20 Feb 1996 02:58:59 -0500
- Organization: America Online, Inc. (1-800-827-6364)
-
- John Nagle wrote:
- >Is there any way to remove a Gestalt entry? I'd like to do this
- >when a driver gets unloaded. Resetting the Gestalt entry to nil
- >seems like a bad idea. Any ideas? Thanks.
-
- The easiest way to solve this problem is to use the GestaltValue library
- from Apple. It gives you three new calls (which are traps in System 7.5
- and later) that make installing, changing and removing a Gestalt selector
- easy and painless. The calls in the library are:
-
- pascal OSErr NewGestaltValue (OSType selector, long newValue);
- pascal OSErr ReplaceGestaltValue (OSType selector, long replacementValue);
- pascal OSErr DeleteGestaltValue (OSType selector);
-
- I've used the GestaltValue library in lots of code and it works great.
-
- - Jim Luther
-
- +++++++++++++++++++++++++++
-
- >From nagle@netcom.com (John Nagle)
- Date: Tue, 20 Feb 1996 19:06:25 GMT
- Organization: NETCOM On-line Communication Services (408 261-4700 guest)
-
- jumplong@aol.com (Jump Long) writes:
- >John Nagle wrote:
- >>Is there any way to remove a Gestalt entry? I'd like to do this
- >>when a driver gets unloaded. Resetting the Gestalt entry to nil
- >>seems like a bad idea. Any ideas? Thanks.
-
- >The easiest way to solve this problem is to use the GestaltValue library
- >from Apple. It gives you three new calls (which are traps in System 7.5
- >and later) that make installing, changing and removing a Gestalt selector
- >easy and painless. The calls in the library are:
-
- >pascal OSErr NewGestaltValue (OSType selector, long newValue);
- >pascal OSErr ReplaceGestaltValue (OSType selector, long replacementValue);
- >pascal OSErr DeleteGestaltValue (OSType selector);
-
- Do you have a URL? Apple's technote search engine is down today.
- Thanks.
-
- John Nagle
-
- +++++++++++++++++++++++++++
-
- >From reed@medicine.wustl.edu (Thomas Reed)
- Date: Wed, 21 Feb 1996 09:50:51 -0600
- Organization: Washington University
-
- In article <nagleDn21vn.1EK@netcom.com>, nagle@netcom.com (John Nagle) wrote:
-
- > Is there any way to remove a Gestalt entry? I'd like to do
- >this when a driver gets unloaded. Resetting the Gestalt entry
- >to nil seems like a bad idea. Any ideas? Thanks.
-
- There's no way to remove one, but you can fake it! ;-)
-
- If you can find a way to return a pointer to a function in your Gestalt
- handler's code resource, it's easy. You can do this several ways. One,
- install TWO Gestalts, one that returns the address of a SetVars function
- (for setting some variables internal to the code resource), and another to
- tell if your driver is installed. Two, have your handler return a pointer
- to a block of data containing your return value and a pointer to SetVars.
- Depends on how you want it to behave.
-
- In the code resource, define a Boolean global variable to tell you whether
- or not you're installed. Then, when your handler is called, check the
- global and return an appropriate value. To "remove" your handler, call
- SetVars to change the value of the global to FALSE.
-
- Good luck!
-
- -Thomas
-
- =====================================================
- Thomas Reed Washington University
- reed@visar.wustl.edu Medical School
- reed@medicine.wustl.edu Saint Louis, MO
- http://medinfo.wustl.edu/~reed
- - ---------------------------------------------------
- Clothes make the man. Naked people have little or no
- influence on society. -- Mark Twain
- =====================================================
-
- Opinions posted are not the opinions of Wash. U.
-
- +++++++++++++++++++++++++++
-
- >From dnebing@epix.net (Dave Nebinger)
- Date: Fri, 23 Feb 1996 10:34:37 -0500
- Organization: KHP Services, Inc
-
- In article <nagleDn21vn.1EK@netcom.com>, nagle@netcom.com (John Nagle) wrote:
-
- > Is there any way to remove a Gestalt entry? I'd like to do
- > this when a driver gets unloaded. Resetting the Gestalt entry
- > to nil seems like a bad idea. Any ideas? Thanks.
- >
- > John Nagle
-
- How about returning the status of the driver (loaded/unloaded)
- in the Gestalt selector? Let the gestalt user worry about whether
- it is loaded or not.
-
- Dave
-
- ==========================================================
- Dave Nebinger dnebing@epix.net
- The Alt.Sources.Mac Archivist
- <http://www.AmbrosiaSW.com/alt.sources.mac/>
- <ftp://ftp.AmbrosiaSW.com/pub/alt.sources.mac/>
-
- +++++++++++++++++++++++++++
-
- >From jonasw@lysator.liu.se (Jonas Wallden)
- Date: 25 Feb 1996 13:00:05 GMT
- Organization: (none)
-
- jumplong@aol.com (Jump Long) writes:
-
- >The easiest way to solve this problem is to use the GestaltValue library
- >from Apple. It gives you three new calls (which are traps in System 7.5
- >and later) that make installing, changing and removing a Gestalt selector
- >easy and painless. The calls in the library are:
- >
- >pascal OSErr NewGestaltValue (OSType selector, long newValue);
- >pascal OSErr ReplaceGestaltValue (OSType selector, long replacementValue);
- >pascal OSErr DeleteGestaltValue (OSType selector);
- >
- >I've used the GestaltValue library in lots of code and it works great.
-
- GestaltValue is a great idea, but unfortunately I haven't found a way
- to link PowerPC code that calls these routines. I've looked through
- the CW8 libraries and the latest Developer CDs but couldn't find a
- stub library where these functions are defined.
-
- ............... ....................... ...................................
- jonas wallden internet e-mail world wide web homepage
- mac hacker jonasw@lysator.liu.se http://www.lysator.liu.se/~jonasw
-
- +++++++++++++++++++++++++++
-
- >From pottier@drakkar.ens.fr (Francois Pottier)
- Date: 25 Feb 1996 15:53:09 GMT
- Organization: Ecole Normale Superieure, Paris, France
-
- In article <4gpmgl$cvf@newsy.ifm.liu.se>,
- Jonas Wallden <jonasw@lysator.liu.se> wrote:
-
- >GestaltValue is a great idea, but unfortunately I haven't found a way
- >to link PowerPC code that calls these routines. I've looked through
- >the CW8 libraries and the latest Developer CDs but couldn't find a
- >stub library where these functions are defined.
-
- GestaltValue doesn't exist on PowerPC. This library was needed because
- it was rather hard to set up a Gestalt selector with its own global
- storage. Now, any code fragment comes with globals so it's much easier
- to write a Gestalt selector.
-
- Agreedly they could have provided it, if only for source code
- compatibility.
-
- --
- Francois Pottier
- Francois.Pottier@ens.fr
- Francois.Pottier@inria.fr
- http://www.eleves.ens.fr:8080/home/pottier/
-
- +++++++++++++++++++++++++++
-
- >From jumplong@aol.com (Jump Long)
- Date: 26 Feb 1996 02:39:14 -0500
- Organization: America Online, Inc. (1-800-827-6364)
-
- John Nagle wrote:
- >Do you have a URL (to GestaltValue)? Apple's technote search
- >engine is down today. Thanks.
-
- Sure, GestaltValue is available at
- <ftp://ftp.info.apple.com/Apple.Support.Area/Developer_Services/Tool_Chest
- /OS_Utilities/GestaltValue.sit.hqx>.
-
- Jonas Wallden wrote:
- >GestaltValue is a great idea, but unfortunately I haven't found
- >a way to link PowerPC code that calls these routines. I've
- >looked through the CW8 libraries and the latest Developer CDs
- >but couldn't find a stub library where these functions are
- >defined.
-
- and then Francois Pottier wrote:
- >GestaltValue doesn't exist on PowerPC. This library was needed
- >because it was rather hard to set up a Gestalt selector with its
- >own global storage. Now, any code fragment comes with globals so
- >it's much easier to write a Gestalt selector.
- >
- >Agreedly they could have provided it, if only for source code
- >compatibility.
-
- To use the GestaltValue 68K library from PowerPC code, you can stick the
- library in a stand-alone code 68K resource, and add some wrapper glue that
- loads the code resource and calls the routines. I wrote that code tonight
- and I've attached an archive below in BinHex 4.0 format.
-
- Since the three GestaltValue routines are available to non-CFM
- applications if SystemSevenFiveOrLater is defined and true, my additional
- code is added to your application only if GENERATINGCFM is true or
- SystemSevenFiveOrLater is false. This allows you to build your programs
- FAT without changing any of your source code.
-
- The archive also includes a little CodeWarrior PPC test program just to
- show that it works.
-
- Hope this helps(tm)
-
- - Jim Luther
-
- (This file must be converted with BinHex 4.0)
- :&&"33b"(CA0dB@ad9Q&XG@8ZFfPd!&0*9%46593K!*!%*#N!N!55fP0*9#%!!3!
- !*#Pb6'&e!NF!N!-@E(3J)""38%-J4f9cG'&XG&CKE(9P!*!2I%X!N!-j!"-"D`)
- A!*!$#3#3$iB!!!-!rj!%!3#Y9QqZV9Cr(!#3"Q!!N!FMS`#3#R-T!!d14f9cG'&
- XG&CKE(9P,QJ!N"%iK3#3%4B!!!(A!*!$&[q3"&4&@&408&-J!3#Q)cjlV9Cr$!#
- 3"J)8!*!(i3!!PK`!N!D,T9KA6[`i4kj(0MReF,A*`[l(9R!af,r%'Je-K!UND
- M&),@[M"f"h&(Gj!!mb8c3U%3!$eNXj%rNm%%0Jckb(h!FYL(C-!FmL6(Z+!,"N%
- 1K32N#rY3a1F9#[mYUdcNErNc3PjI"ZM9Ul8acD@cZ$VU,"f-[AS*Dj'8(r+Y$Xk
- 4h5i1BaV2mN1H)1IeJDDZE0BA6QDD#f[j3PjrKP$)ZX-HGa$Bdi`)!CX[ZV4p%0[
- 6H##%I8'I"d25G`"$Q5$NLqENLdf@icXq0ZMfq$j6L(04!emSPh1MdL#iC,X*)V-
- @P`!0!"&(CA0dB@ad9Q&XG@8ZFR0bB`#3$S6q!*!4KJ!!"a`!N!-@rj!%FR0bBe*
- 6483"!+e@A@qY9QRa!!!(2!#3"J69!*!%6aB!N!KBZ50%$L)UHC1S'*8%bA9TT+@
- j1p$@dHa[k5!+VFfpeIC+dH469DUSme&Cp8TZQ**LVT@8,2ITKKjcNT0%RaYT#6U
- 1BMBmm06j[Vhf`jU0U*C99AqkE1hMZ80*ecRIlPjhaY4%qBTPMVQK6aBYl6%cM[Y
- A*KDYZTGU%V0RVDDDHSqrU@VZAj4h0kfJd#H,Akm[UCr!0Y4Xb&"9p8YY$Gmj%ci
- +cUK9U+ERCUJ'@DT"rkS+ZCm2V5@UVkK9UDcjVD,lDhHK1cqVM9c0EcR[3DqZ9A1
- (3ZIiEJePGh3fYiH3!"`UiP4%qDJL3r88HTKk6feLR[9Gb@$&cQ5rT#5U@"q9eF"
- 6b'kr5P8pmpVrKLUf8-r%ceq6'-I!%qiPPm8-$(H`NZk,l[p)qSI,YrcN6$#8k(1
- TUZ1ebIYc"d2RX!hKVY!"fc-4NkKQRVAlJp3fh,Drab8Q+I@Yh&ZV+1PLC6e19P@
- ,*'D@R(VCU4fe%9B"&b6hCZLF8&Bi%([E`ECA+LF[aMa(q+JFFkdrkmS9brEHQR&
- -4CEmHS%qp-N-@@JQQhVrVBRbj9YbKfKm$cNZUVM)5KJBTm-@SiD90,q@qf90fmF
- r@E2V$+TBqC-c%e893A)QTPL*SNE1UT8@KaR66@,,K"23EV+e-jZ5TfBQLRRLaTe
- "Q#EemT@@NZml5S+D1pMqUTLq)8fjArE82R*0SQC@#lR@A&PI)VM4YH4U%h1lXqK
- ECdbeAC!!*c&T8EPIGYqAqkA3f,ilrIKJa9PAe[X`C6Z,SR-hj0i82+(UPH%$1qk
- r,rGQZVE@PhXc%hjZQ,RZR(*U'r-NbTB21KRF,"C+)D[KThQ2VkGNN!"1&FTq)Sf
- hKQGH9&BKR!*bHeP9pdH1T!*1G@G-aBcN*)llZl6#cjLkDQ@b)[+496Z5al(9HkE
- f9!(4L@dLA#UdePYT`P3hjCi6Zf(mckPFE!IESECA5X8mUd-21lCL'rM#RD*KQE2
- S%hqlI!09)2mp4kDFeBp-14XIQh,8@PGaiFL86l!B+dCQX0@H`54+PLa["EF#ZE5
- +D9a-bjEpj-bHlSH[5E6ec+Kp41JK9bKpCAK@TUb+A!8dT#2F8A-rTN69[90`3US
- LfamB9Tm8@0lZ$081cfV#IXcS'BHCP65HfTfq5rM0HUhUaGa2lBdXE@)LEK2FaV#
- *PqDc9p@A0#ac1DcdM6ej4T8$Gm$13iF&*qXefLmfSfZrYMXCFG3*qcXRV1ANdEp
- h3LHY`TidTNbJ@r-SHFZD0$j$2611c#0j5D$IqYXmHP#Si*DA0[CjF@qN[[AELqD
- fjAlCr0DK"A9P0iXpTV6hdNbL(@$2ZJTlq1@[3U1C)FHmi9H'pBN(YYmpTED0953
- UcPMXC'+Ra*6fR)f*1SrpTGcMXcI2a6hB@+fli@RrTGKLVDb*A@E0B8AZ6A+KDk8
- b*%ph!'c-CQ58IXC8l'LpF#4dB&2a`Pp-UA@hR"#jK@aJ'rC-m`e[G2U[$hfpCX2
- iU3e69cQ5VVYEHjbhYrTfKEiZCN9B4V6heVYEkmX%X[k6YlIqb3[*+Z5R%hI5aNm
- ZEl*[)NM!D-hBPqdCqd!h!,T'k1VZ&,VqeJ9@ReIh&qT(XGqb$lacpc)6rkEUK-m
- !-G%mSX#D5"5BPSD**ZE[eZl,pbS!N!30&NGPFh4KE(4@B@aeC5jbFh*M,QeKDf8
- !N!N,p3#3%!(A!!!)R3#3!aErN!4849K869"6)!%!Ul&M-+e@I``!N!B#63#3"J%
- 4!!!bB`#3"[#58E8!!#Crd+FPlr6Fpi@a1iJlZS1F,aQ&N5Fjbah`#AP-eidbI6J
- Ap+#eaCq1h#JlKb(L*Z53!-FAcXN[,1lc*K*K)*mEql`j#$-lj(9Rbi$*Piii)J,
- +KM+3!+V40!5TME@U&'e+!q#`#SA#@NN*9fQL3j!!aB8a52H"S$m8m(P"KKq&F8f
- K[99ESpk9"TU"bF+NT089)2JQU%1KF&AM-(AUKKN!'"#6R!U6,%3Hj"MN)%XHi%`
- c'R)%5`J$IBFd9l08T4V)NAZec$hN#eZJKh5RN8XEqB,3lFeP$i"9ClB"H6Kc09B
- 3mJE`#NP*SJ'jir"pi8%LF`Ml8)EE3hU90Y&ULFZqmf&mYr&R5eD!RY6k2,N%!!d
- 54f9cG'&XG&CKE(9P4faeC5jME@&VC3#3#DHm!*!3"a`!!!V'!*!$&[q3"&4&@&4
- 08&-J!3#VX@-`V9Cr$!#3"J0Y!*!'!EN!!))m!*!'@%C4#UP3+NeU(H4m!%2JF3H
- $S,8[M0e"h0(0Kr`3F!-2p2S!mS8KKc`qN!#"B"B*Y4eki'ECS0rMaRiB)KTNdXX
- 'EIeC`-*KaSGLQ30rd+G05PVU4F+k*jEr'Z4!PMZEZ0S3X4#j-5QMl`q$X$Z,$IT
- bpId3kHH#0,#3!1BJkXF-j$#[J38Pb1rKFaVK4e`Q3elGC4CpGaLNqh`K`#)BmAY
- pAL$5T3&cQJLi3ekHPSS-LCZIlJrkF6E)J!MiF4K!eNHU36XJe9458ZVNe-'6K9+
- &8&L,P"G`a2!09cEV#bFccCG%@[jq2Uq9q&r'#UX'd4F*KEQ$2'9)4i%r!08F@
- ASp3Khkp,0S2VM%RlIXJ(-RfN)Sm,jI32,#4lF9'BGm(G%#d&FAl5Pa1RjSFFS50
- PN!#l-q)Y''eH4mMJa%BHc#%IU9ddeH@(kT'&3aBAaQ4F@@fj#'U%AVNl#%P,eem
- 5(i9a6Air3hHBI(Z8#24lNrKDeGAf))dGLX)"`L5&&+6j-1$B(%8hK&&fEZR)+3Z
- 6BUK5FjX[ZUcXHf"&SVB%e['a3EI(Y`,i,,@!0Ra"(el*I"UU#3F*p`-!N!30%NG
- PFh4KE(4@B@aeC8GXG@8ZD'eKDf8!N!PXYJ#3%!LG!!!1d`#3!aErN!4849K869"
- 6)!%!Ul&M-+e@I``!N!B-eJ#3"J1G!!![Y!#3"KE)#dlaj2%%'F#%(Z'%i5qbNT@
- GNHH%%8ijjH4@[SCRNT8I05AikrJ4IS56S`5!iJpi$5pC25m#m0(M+am3p#-@Z+l
- Ne'24DifXj8@14KKj4LDF(#FSi%Gq*Fc((p"E!Ma[ZDf@Fj4A#%C#`[)FMP!EPTX
- IQ"9a!3`5Q5)Se,*5#F*%bB*%BGJ$9TBj6jMK8P!-Qq4X"Yra!SiVNk'DDelc(,p
- bPV&XhNifPrmN+bMBM+)Q8T95-8-X-Uj"Xk,-X8R2"H'C%B"PCJfAh'5b-MB'm6'
- +*eEA*RpCR@IdLDX8'G0`KLLJ92+#TjM#6MH'IV`$6+6@E4kNT'cmM1IFc'!L&A#
- M3CC)D#JG%*Up&bqqU((SMYYklVUl"#q[+1(ASeQ*ZT0pFbdCm&ma(9$q0l*K2$B
- mVlhq8ZdXDp,*GPbhDHL)5+k+ZDLMSF!e[[jK"mK')a590X6j#Mr*Y@d%+ERYU@0
- eUja+Uk46X#Q9QlTD)d94&Hl[VM0G'N@S,9rR!*lea[(S@IZY[RrSN!"mlq8Vpmp
- pGdP[8SQkR2@4iH+F'LNZ8$3pYL@lS3++QXd&YFRbX*K6R$JPda3!KR'J&(LY%la
- FHSC+*U&4[MH-,5M3Q'0LT'T$,LQb`-[DaYprPbI#-QF*rT0*0Bi&SIb3!1f3!)c
- 0TfL8J8l#")k#Nb$UM[SR4lhAJkYB-"Em!T9QqG`HeL8BKq'#`e[$HmT2TKYmYHF
- ZjKSAcTY1IU6d@,e2["lDp341T(ab9lDVqeH9j4TFAd`N(-!dV"XH'jC-[f8D8pG
- ai!q)JRKm2$U0qcm(R[dil3d2!drche"1U1Td$AcIEkcL8EIhr@Nd(&2Zi$6X4Ye
- "-!SLEkm0DfGl*$jD[eaEfdY&aR5[LHGpQlCm-0edI1X$8PT!Zh5DD-0!MdE2qSj
- iP8B906ZRIEdX&N2&FAiK!YCpGBmplqBmqmXSIKXHleBE[-A1S(q,U2i+e[f4H!I
- XGJAp"qlpJISEhQhX0a!h9f($m(pLMqGR#BcJe%0T@m"4m&SV$Vkh6D(@6p'h%C6
- bI9lEUEX0&`jr$++`jqk@LTdAM*j[QTF'P[0cF9#`j-YAdi9emdS4Cdc4Na!p)e@
- *J44eSZJ4L#Eqq1LBRbQQCN")kDZ8p"c92%[-c9BdDlAGMT[&kpcSpPhRFH$H5FR
- `BG1ZPIYfL&c0j!GJDmRY+m46UHK*#XfL8pF$HX#i#'ac2QbbIhI@'Q&V[VSq!`d
- 0'&"33b"(CA0dB@ad9Q&XG@8J8Q9KC#"0C3#3"fq*!*!3#XB!!",a!*!$&[q3"&4
- &@&4dG(Kd!3#VX@-`V9CP"J!!!V3!!!B9!!!"33!!!QecjSEH!*!'kLd4!!J!20X
- kR#(89VQEYB6m26[h"I3D6SI#85KB-"p!QC6#dELDN!!mS83Jd"UhTCQ5T-[Z*$f
- ,iUk8K,'I%Jpi)*5NFAe)bL(5kE8%@MUGaYp[Rjj5#b!(FeVI9E1kdp$4!YUP3iR
- N#Beadc+TKGYG960RmS3CSfE[d"f&QY"Z'*,YQ1U82+(TNe'Sd9)pffe2V62F(Kh
- L01K@EcVic4E9SB66bTFmS8PTTde&YcfeJhA,cpGQ"JPelPmi'U0hI"PRpf1lli)
- LCTMT8"KLR0@Nf91G"38K(m3i#MX"mj%,CR[LMccb33kA)p[$qSakXMl)iBGpd)I
- Iqi-FardIj$JHrM$REcl-qIi(1FkG2XKa([9KcT%2FhlV`jcIr6$RZ3pb"2M`IT*
- r)(,,Fce,RZ-S&'S$C-UKkBiQ`LLP60E$cjHb#U*J*FJ!*U19(EQ9iFQa)mm)*80
- 'eLi**B``FLXjCNqQ`#Y!PM)"mL)!*jj+9NE3MekJLKkHTXImcZX))bKJj"Pj6T!
- !`Ehe!25mm+Ff#h[ja(k`a+'Q9GcDY&V5QllhcV#i'2*XYSpa1Fb&q*+Gjl9(E#D
- QJ+K,1m9lYdkFGK@GYcEC*LDlQ'lj@cAUKLaNBK!A8%dL$4Pr@dZ[MplY@b#N4[G
- !Yba1m9ZC%GaUHAZT9pl(E5jPY&4XbT1dbGTp#@U'B%BD6BVG%kGYFL)f+)"P0CZ
- GMk$qUl'Jl,VHlbE+RJ89$MeDbl90e$K[%DKXZAlNLd[YJ+03[f!I`j8NbHBi*(0
- [5j9b-ZVB$ZI8TrM&'P'B+2&@faj%,h+e90['"6YkG)eB`bA+VPG#+3k`eb)SQq4
- kL3P("[DjX+'16BTiVeQB5Q$K9TkcT-()!&cU3re2EP$l%A@0#YA3(G-dmAV@X3[
- 2DGXkdf,!X#cK!Sfh6YUlY9NFR)RMqNa0NJ8aGAa5)ESJ0N'3!+L6Fh$jbSfXE(P
- rHK)Nl9DDR@p%q)ke#&YeI)(eC(UrqJbG,X!#VX+`f28Ul@pR&$&kb`Mj`(6%m@F
- iG#[K+XfA(cqFcaGdGN`[Aaf9@[d!B'J&F((F"%"iQ*Q+cKVG'3S@RM(9VQR`*4$
- NTQ4T'020`GRa3L2RN!#ST++JD6PX,+hM(F,*M!,PBECJdX0Lk[ED$K$'0AXdYD)
- 6aNEm[0AKd&e60#eZ0Lh!PS($IZRBmIdUU'KDe38RMVhlLZb0MfXql-66'*6KqCZ
- QF'jEMQSQI&b)kq!Cm&ep!IdDU'ZfeHar!*!%$4&38%0(CA0dB@ad9Q&XG@8ZBe*
- PB@3J6@8!N!IChJ#3%!l6!!!A)J#3!aErN!4849K869"6)!%!Ul&M-+e@I``!N!B
- *`!#3"J2"!!"e,`#3"Ukk#dlaj2%%'F$-)kaENkam2AEN1H(NQ0c)88,2j#ZrG8,
- @Cj(MC!D`HX"V!K!'X!*F"1#MaeGq(N%rBS%!VUjVIACV4cLK9q5iC-`*@KMKH)*
- rS)&&@[@dANmkUQ6bKM+K&(ABHD(mEb+)T#C"QFQC,$Y6fSaTEXd5SY(SR%44+*N
- *,ie'M*!!C,DLAq55HU9IX&eV,UAL9dN#`ffdRTaCB9I0E1hbZbPT+9C)R"PE'#X
- m+PP)4diX#m99#9+MT49kf%ChG#2p`T3qa%"0hXSXk"V`0qA9!Tqm5l%3MQE-QJT
- VVQA114fG6DJl15+Kmq#f$P)JQja**If+jXD5p)j-`DJ'k3M9[(caiRQX`cA6HLY
- 0Me'H+T(`aci[$FTGr24"-ei6j2Db[[b$mcjk#E+d!R,!0eY@'M6Q3SQ-pk,3eJ8
- VpMYGm"H@D9C+j5YL*L[RH8Nr0,p[31C*'dpSN!#&9C)YZ5Kh6CS#P%M)M*@j#8'
- Ndprk6C6j1XL%VePIbQXHfKi`"4L1FTj,cARNi"K1cakYhVfM6R[3(Tp0Zi21q@A
- r!c4(faE$*$8A4fN+LCGCXY@1$&TebG9@dpEHVLVKkFEcC`#L1-'cXkTNp*S'EhU
- p8fV9!BRd%YZh)XFq$'&38L#k`V&R40b&r6EZCh%p(GL&+ScmNqQTS8M*ZU6KT'e
- Y6,JeUedEQCqNIk9V2@+@32!ed-A[dc4*%r6@R6qf8Q'V%)Vc4[c'H-(lTKPD6F"
- RE9r1KSN+#MT*%d4ra+E$rZ9QbfT[YaC369F&PZQ6URYaJXlqbIhX,RF-MR,$&p$
- VpNI$mI4X-+A"F0Tq&5F+pMVr6LLM2d%BPMhXGq8p'VGl`l1,L'C[H2jV'lmmVJ0
- -)11Z!1V18*Gb8m'5[3f3!1"Zi@B-!&!5F"E+S!R-bL,5aS&M+L,)U-+@Q5maYjA
- G19ENMFEH@5I8b*UX9Y[p(RPl8RmJS"(-`d1)@I5&e09F`,+VjkC"hcaY536V2Gk
- XA#JqiR-l&f!2Hf&XE@1$Pf88TN(LfJA5pjZP'`)TLe-+@aj2(KECBV2Yi4MFPY"
- F"-GfF0KBKJ-b%KMZ-fX++m-CYpZRHDRMG9CG6)9`m+3iF[6akU(DF",Q"+3UcVb
- aBFRd&@QqLIV$2-CC[+hq-+N"JEK!'i[eQQl@lYBj32baLiMbjcNrR'YhMGf@KI#
- IfGY4m($U2C&J+kXP*ZPV#%3mp2+&LVp[eVX'$qAp4mMpcAX!j#X(*0cRr`,#[Gm
- G"rqfIX`kPr1NeASkTp2r!3#3"!d98&"$4f9cG'&XG&CKE(9P9'9cG#jM)%eP!*!
- (aqX!N"!5m3!!'%F!N!-@rj!%9%9B9%0A588"!+e@CbqY9Rm3!*!'!H8!N!He!!!
- 1mJ#3"[df8EAm)8q3!22k3&0A0ZX,*c20KBP)SE8[M0e"h0%Gj(c*M%JSM%#r&f5
- jr5%aIbN+"`L6l'P'K*+3!#r-"A%6BC)`bH",jc,6-"+,ZV00BJC3VkfPVD@H50)
- N55%&D3cNJPl!Z#-q%)+BmBFb!H0$2L"9m!,5"CS"QbqkY!%e9d)$+Ie5PDS'$4X
- e9NYq0FlB,j3l2MESp[JfD1mdEY5`J8UCqTYfaRkKhI!&IALYpEpMHM1TUA!r$3d
- 98&"$4f9cG'&XG&CKE(9P9'9cG#ke)%eP!*!(M&d!N"!A)J!!)lN!N!-@rj!%68e
- 38N0A588"!+aHCb'Y9Rl%!!!RcJ!!"q3!!!IT!!!$'IUi-+-!N!B(q!h!VCPGDfi
- kU*A6c-e5bqZLRGIDFFU2F-,)bLNrLUFRTjHFFQSRTd2qY&r$8cclY9Df2XGh4@J
- pqE8)Rj!!iq3iM6`Ma`QlhL5FF(*m3&MR%6iKr1h)FF)**mFT1Ak%%dDH05(FMV#
- 1--)bFLc+Mc$#AmPcE`AZbUj*Pfm[TkeX2Ik%d`L,(2F)Lm`iiB4621(!H!m)3+q
- c``-3!*KG!C!!MDIU(UIrZf[[*1$r`3hc1AmrRMqfp13ErIZN@r@P9UYjSH$afKc
- H4TZM8kK(c2LL#P4JX9KVc8hbrBBb*)'"j!D$a0GYAV3X%b"Z0m$Plf89'relRYT
- 3@EC8dp$ce"C6"L,T&8lrTR`M*11T`c1qqY@$QTT[)(Q*VU'([R9VRUkYVbQ)VHU
- EdHph9bqUlL`!L'AdBYQR(Z!l`Kp!(BX"eBd!&9q5Y$Ri3X@5Car0G5`dS-*%-BL
- XaG[[1FG$K5bd#J!Xj+LNLL4EE,bKTXk!T@S`jjYcFid[$QIK@#%%,S&l!eP,TUM
- Z'-UM4cC0C"[*L,Q'm[VdGDcI$r'G%@*TGFYTr(j#Jd)cT5Z0pHX"L[hd#qJb4@0
- a1@fmDe`r0H5!PVbTmJA[KaX)RTF835c91#"aPGfj3K#2-)PQ5#Za@UXQ#fi*RL9
- ZYd-CJ)I&8P8DbC0BC@mch,$5l4+p90VM15c@UR+&!"j0jZZ9!A5YVDXG*ALH4he
- CFlh+b*r1Sl-d56h[P+S5$l@4cme9"1!4Bq42#r)($lGLJ+lZF5,RH!KGT`Aj0D4
- kAIj2[5B(HB69q"rbX0Sm[-da*UbNUp[Q83VJ`BmV'p'9'K[+3d0jr0b*c[*3'Br
- iQk')U49ZMp4VXlNQkKZ5DC,bX(0SGr'GrlB1eZp&MaKZpK-m2-XGEC%mLGDb-kS
- L$fqR3J!2'QSM9XRIZPTT,8S1pqS&0bUA1&b8pRL1#`lh&!r&!)GE8eTTL1TKX6C
- &p&"UF-SReEMJP--mcMRP+)m*Tac9GF)T4hJS,cMP86hqFXURK$h[P#-m*Tcb+)f
- ,6MR-3aR!+5Yr10b6"A["iBje4X8!KpYNGejCD1KDF28*Kk[pdqNJN4-jrR3kB4l
- R(%T8M`Q(%Z&aYJ12mVMBJF-mBScKVKH22,$`SeCiXX1%H$MXife[F*)`9QQ8KkZ
- YBja(69Y(K-F8bmPeK@"a@-biUD-%%,pecRK8JeAd'4lBU4cMAM'&mR$B2"k$fEA
- 5EAFF9PIZ$&M4`P*&!&dR1d2)5iFpq9NHN3iFUE03jr51PpP%D!aXkBIJ&Sm@#$&
- "#q+YKcC#blbp%JE`"N!,jr[N%*jpR)rcIIV4l&EFq%Q#(CKj$Gi"0kL!9((GMl`
- ,,I-VS2@(*H$lE$[ilZlLI"Zdl)h[,Qb(P)R%cj!!c(A6I&ch`jr"V4rI0m`&%Gq
- p6`i),Yea6``$mb1rJH#kYmlNZVIJk`!rQ,S)GZ!ja1IZhG"5[![[,c%Z[BccIPM
- 2P*k+@C%af3QUZ5CTP&VAkDEGf93Kf0S&d@0UF0TAi4e((2),lYjYKdM4Y3@%Rhi
- 9iG2fNU+Cfh&4kLT+Q2#TbD83V`0GPMiSP,jNCk3HLHQ,PaR!"hK3A#Aa)8AAlBS
- @p"l`3$rdNU++MfJP%(iD1J3pkT-Uf8IGV2XJjF%RXb&HcI4iM#aNTa4TN!#*@e@
- Up*%D3&3@ACrB#bQ2ji3%bj1U%V15MUm,30q`#mmGbrd(1-6RiMXrk#r03k`Icf5
- BfPf2qGr)"V8DFF0!IN$F+Z&jAT,lcLB2,pTK'JjP-6rE,1[S`ek!qV$mmCKrhhE
- 3TiAf`V,fVq(@[H"&""X"jG2h,1Jc0T2VG9E%2N"qDeQ[5hRm6LNrkN(ckc0PDih
- kdhdq@J264fS!MCpS%qf#a`5+$cA!V4ZV!E,LmpH8"'VJ#P119A4e#,cA81HeHHd
- ZTb#ZRQ[kk8f`5T4)qN$55"qJZiiFFU+FP9&k)BUTaDhBK$Vl5VG$-*3+`Z5%@l%
- M#"!PQ#,!d)0DAZ`G@RP1K$JX%AB%AVk&'p+rE##IL@)-DAH*q*U2l!"I$-SR#"l
- EG%DH)bN,8FH!e#%R("d(DDP[$h,k31UP``eJ@,mEr$iM8jLJi"2k@i(a"kdB
- bk5&'*EA0iF$qbFbEiNH&%(hJP`c+-r%URG"GF[3['S0*"[e2`*[J2aZDIjN%+J#
- 8lB"61ZU6L&SaaX"),Nplq&FMSIqSN!$RPhdl[4QIc#"18,NEfFC$ZP[%pBCT-+H
- Z[MB,-`lYX-lEbYB&d$hMlc,@33CHM436"+"V!3YBArJ+k0V)Za6,f`5i5d[5+9E
- b+0b%@#(&CRd2b*Zd8``*iLbI2%HaaPX!hqMh8qb@pq%fJ2qR8Zc+qk%,i,*XLU8
- @`Pf)&9%XrJRS3DbDBSkGm"$qh)2Pbmf%Ta&MHm@9VI!+BMG6,'iMR6SCf!5l*4p
- `+QjJUaaY-`$lPQ%9a9BIK(f)2F"i2!-(!$,CU(jq$Nl*B*D6BU9[N`3FCH(%#k1
- A6YkbkB34BVjP'11A*%mMXDim1)e-C1Y#`H@5",S`CRDe#`X&TcDd2-DH"6)RbJc
- +ZVbLcD-TDlGlAD+kh1AdDZTYiM,"Ub[KH3%h9U`flh*mcp)Nd&eVQ9KSljSpNiP
- *'e#b&!'ib5BklFjP(Sfjh),*NJ+,Nh)@'CI6*,$"5B"Rk!mQF46#p6[f2-"AKqZ
- +34lr!3!!#X"&"hlQ-@85GQ4##5-d-U,N+,Q98$*KK"&'MK%U)bYK+cX*95DH8#p
- lFS```[$8NlC+$Nq9%Ia(k)#``8TQM%`CBB3G'E!M-dBBBB5YNJNPamL!N3Pl-Q#
- %N4%l`JJlFT3-Q16B%fD%N3RYb6%bSJ,h5DpENa`MafiY`Xl%%dD1%43aB!,JK99
- HHG-d!)$Jf`-3Q-2h#Xi8I&[aIB6G!%M3&mLBC5Z[f8#H2i0,-&QXI8j!%!Qd3Pk
- 2*8QF&j(9I'pDRl*85dGUNI(D28KJJiFeJ'pIp-L*c0!'m"$MYAN%`48me0HGFG4
- 536A-NYCli1"`Ep)XD$!1pmM5jC8kE4&h-LJP,YEJ#9NP(kA$dL$1RY)*pLr*Bl+
- %rBShIrH&m4jDN!#pM0ZYS)iJm`J[0SNT5[+BCMZUiH48Skc&mhAG'b@fhHAQcZp
- &GUbk[r)!qk$AGhKpTpH([$jFe6pp`2i8R'CZE1MIdp#IaGRh(83EqS@Zb+f(Yk2
- BTq"ibe[XT8epR8-P4l1QeEb'VQbZPK@kK&964d"@RH+1"&BdEhlTL-VMbG&bbG&
- RY2Lf(*%D3SIBMkHMLb90XVmrMJEkV86iVDQ$*eE59i%4mNG(*$-d-MEa9mCk#JS
- G`LmLMqTKC0R@9KlYqVVM"+TiCIZHF#2T19+4PA5+6N$L90m"EQ4i39#(&k#&8CI
- mA+Q1h%b3!)TG0+ES"&SCpBfI)RHZ6e+U8jkL%fLMe0F,IQDiXI4ZEd-iJAC'[H%
- ldJhhA21S1-&mPi!%ArMh!+E['UPNMdjNhGb&Fa"-B#iXh`r+fSaTcFH,cEfb@i"
- 4f56%UH&4cHEhf!p`JpVK8@9p6L[)H#RpSiBj0C!!R6qlTC04k6A"UA65bDQKNFb
- BSaXrZ3fY%HkKD0e!hp$dBZ%HBVG,P&2p5mM0QE2#HHBXjKrhkdjHZMPpP96S2cU
- ",VlAlU4C+ZL1ETC8!dpFbfaXQ0eB`Z9h)HCj++8EfalDG!12CVc(39)bfTPDE4f
- %I`M32c6cbH,d"(Elk*@UT'f(84HR6q**YSE[959Pf262Ib%K%&"33b"(CA0dB@a
- d9Q&XG@8!N"3j!"-"D`)A!*!$!3!!'%F!N!F@!*!$KJ!!!`$rN!3"!+e@EkkY9Rm
- F!*!'B!#3"b-c!*!+19M6B3!!:
-
- ---------------------------
-
- End of C.S.M.P. Digest
- **********************
-
-
-
-