c++.stlsoft - using scoped_handle
- Adi Shavit (17/17) Nov 23 2006 Hi,
- Matthew (5/19) Nov 23 2006 None off the top of my head.
- Adi Shavit (35/35) Nov 23 2006
- Matthew (47/52) Dec 26 2006 Ok
- Adi Shavit (5/16) Dec 27 2006 Yes.
- Adi Shavit (64/64) Jan 31 2007 Hi,
- Matthew Wilson (21/81) Jan 31 2007 Seems like a hasty implementation on my part. I think the better solutio...
- Adi Shavit (71/71) Feb 01 2007
- Matthew Wilson (57/57) Feb 01 2007 charset="iso-8859-1"
- Adi Shavit (8/18) Feb 01 2007 Actually, I'm not sure I understand what you mean.
- Matthew Wilson (46/46) Feb 01 2007 charset="iso-8859-1"
- Matthew Wilson (51/51) Feb 01 2007 charset="iso-8859-1"
- Adi Shavit (6/68) Feb 02 2007 Got it!
- Matthew Wilson (113/118) Feb 02 2007 Still going to be a while before I can do STLSoft release, so am includi...
Hi, I have a 3rd party lib that provides various create/release functions for various types. They all return a pointer to the type (some are opaque some are not) e.g. Type*. I want to use scoped_handle with these to give me automatic release when I go out of scope. The problem is that the all the release functions accept as a parameter Type**. This is, purportedly, done to that the release function can zero the pointer. This means that I cannot use scoped_handle as RAII, but only as a separate object defined after the bare pointer (in the same scope). If I define a forwarding function that accepts Type*& and forwards to the original function (as &arg) , the code does not compile. Any suggestions? Thanks, Adi
Nov 23 2006
I have a 3rd party lib that provides various create/release functions for various types. They all return a pointer to the type (some are opaque some are not) e.g. Type*. I want to use scoped_handle with these to give me automatic release when I go out of scope.A jolly good idea. ;-)The problem is that the all the release functions accept as a parameter Type**. This is, purportedly, done to that the release function can zero the pointer. This means that I cannot use scoped_handle as RAII, but only as a separate object defined after the bare pointer (in the same scope). If I define a forwarding function that accepts Type*& and forwards to the original function (as &arg) , the code does not compile. Any suggestions?None off the top of my head. I'm done with my post-book break tomorrow, after which I'll apply my mind to this issue. Give me until after the w/e, and I'll see what I can conjure. <g>
Nov 23 2006
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type"> </head> <body bgcolor="#ffffff <small>Hi,</small> <blockquote cite="midek3riu$ure$2 digitaldaemon.com" type="cite"> <blockquote type="cite"> <pre wrap="">The problem is that the all the release functions accept as a parameter Type**. This is, purportedly, done to that the release function can zero the pointer. This means that I cannot use scoped_handle as RAII, but only as a separate object defined after the bare pointer (in the same scope). If I define a forwarding function that accepts Type*& and forwards to the original function (as &arg) , the code does not compile. Any suggestions? </pre> </blockquote> <pre wrap=""><!----> None off the top of my head. I'm done with my post-book break tomorrow, after which I'll apply my mind to this issue. Give me until after the w/e, and I'll see what I can conjure. <g> </pre> </blockquote> <small>Well, I guess a wrapper that somehow (how?) binds the pointer to the first argument and accepts a dummy argument of type <big><tt>Type*</tt></big> that is not used. But this is not really elegant.<br> <br> Adi<br> </small> </body> </html>
Nov 23 2006
Any suggestions?Well, I guess a wrapper that somehow (how?) binds the pointer to the first argument and accepts a dummy argument of type Type* that is not used. But this is not really elegant. AdiOk I've managed to get an effective solution. It's a prosaic, but functional, solution: just overload all the ctors for the by-ref functions. And the function translators now have another member type - indirect_function_type - and another method - translate_indirect(). I wanted to do it with an adaptor function template, something along the lines of template< typename R , typename H > function_creator<R, H, ???>::fn set_null_deref(R (*pfn)(H*) ); But as you can see from the ???, there's no way to get a function in there. The answer would be to have the function_creator class hold some state, but then that would require scoped_handle to understand function pointers and some special kind of function object. It all seemed too much, so, even though it's an exponential solution - 6 more overloads to cover all calling conventions and compiler weirdies - it's the way to go. Not to mention that, despite the extra complexity to the library author, it's a great deal simpler to the user. They just continue to pass the function to the s_h ctor, e.g. handle_t handle_make(char const *); void handle_close(handle_t); void handle_close_set_null(handle_t *); { // old form handle_t h = handle_make("abc"); scoped_handle<handle_t> sh(h, handle_close); } { // new form handle_t h = handle_make("def"); scoped_handle<handle_t> sh(h, handle_close_set_null); } using the adaptor would have required something like: { // new form with adaptor handle_t h = handle_make("def"); scoped_handle<handle_t> sh(h, set_null_deref(handle_close_set_null)); } So the extra brain/finger strain's just for the librarian. In any case, I think we're pretty safe from having a request to to R (*)(H***), don't you agree? ;-) I've a whole heap of testing to do now, to make sure this doesn't wreck anything, as it's a pretty fundamental component. But if it's good it'll be out with beta 35. (When, oh when will 1.9.1 proper ever get out there ... ? <g>) Cheers Matthew
Dec 26 2006
Hi Matthew,Ok I've managed to get an effective solution. It's a prosaic, but functional, solution: just overload all the ctors for the by-ref functions. And the function translators now have another member type - indirect_function_type - and another method - translate_indirect().Yes, I guess this /would/ be the simplest solution.<snip> So the extra brain/finger strain's just for the librarian. In any case, I think we're pretty safe from having a request to to R (*)(H***), don't you agree? ;-)Yes. Thanks! Adi
Dec 27 2006
Hi, Another question/remark about scoped_handle<>. The docs say <http://www.synesis.com.au/software/stlsoft/doc-1.9/classstlsoft_1_1scoped__h it: Provides automated scope-based cleanup of arbitrary resource types without any memory allocation required to implement the generic support. The template is parameterised on the resource type (e.g. FILE*, int, void*) and instances are initialised from a resource handle and the address of a (single-parameter) cleanup function, as in: <snip...> FILE *file = ::fopen("file.ext", "r"); ::stlsoft::*scoped_handle*<FILE*> h2(file, ::fclose); Also, the class provides support for indirect cleanup function like releaseAndSetNull() (Thanks!). However, note the program below: #include <stlsoft/smartptr/scoped_handle.hpp> int* getNewInt() { return new int(1); } void releaseIntAndReset(int** n) { delete *n; *n = 0; } int main() { int* i =0; //stlsoft::scoped_handle<int*> fgdet(i, releaseIntAndReset); // this will NOT release i i = getNewInt(); stlsoft::scoped_handle<int*> fgdet(i, releaseIntAndReset); // only this will release i } My remarks might be just to clarify the documentation to specifically explain that (apparently) a COPY of the handle (e.g. i) is taken, and the release function is called on this copy, and NOT on the original (via a hypothetical reference). I somehow assumed that a reference to the handle is kept so that in the program above, i will be properly released. For example, with indirect releaseAndSetNull() functions, the setNull part is essentially thrown away, while the external pointer is left dangling. If it is in the same scope then this is not a problem, but say i above is a member, which get tested for 0 and allocated and release repeatedly in different scopes (e.g. methods), then manual 0 assignment will be required and the whole point of the scoped_handle in this case is missed. e.g.: int main() { int* i =0; { i = getNewInt(); stlsoft::scoped_handle<int*> fgdet(i, releaseIntAndReset); // release i, but not set i to 0 } int j = (int)i; // j != 0; } Of course, I can use the internal handle directly, but this is not always possible, and makes readability slightly harder. Adi
Jan 31 2007
Another question/remark about scoped_handle<>. The docs say<http://www.synesis.com.au/software/stlsoft/doc-1.9/classstlsoft_1_1scoped__it: Provides automated scope-based cleanup of arbitrary resource types without any memory allocation required to implement the generic support. The template is parameterised on the resource type (e.g. FILE*, int, void*) and instances are initialised from a resource handle and the address of a (single-parameter) cleanup function, as in: <snip...> FILE *file = ::fopen("file.ext", "r"); ::stlsoft::*scoped_handle*<FILE*> h2(file, ::fclose); Also, the class provides support for indirect cleanup function like releaseAndSetNull() (Thanks!). However, note the program below: #include <stlsoft/smartptr/scoped_handle.hpp> int* getNewInt() { return new int(1); } void releaseIntAndReset(int** n) { delete *n; *n = 0; } int main() { int* i =0; //stlsoft::scoped_handle<int*> fgdet(i, releaseIntAndReset); // this will NOT release i i = getNewInt(); stlsoft::scoped_handle<int*> fgdet(i, releaseIntAndReset); // only this will release i } My remarks might be just to clarify the documentation to specifically explain that (apparently) a COPY of the handle (e.g. i) is taken, and the release function is called on this copy, and NOT on the original (via a hypothetical reference). I somehow assumed that a reference to the handle is kept so that in the program above, i will be properly released. For example, with indirect releaseAndSetNull() functions, the setNull part is essentially thrown away, while the external pointer is left dangling. If it is in the same scope then this is not a problem, but say i above is a member, which get tested for 0 and allocated and release repeatedly in different scopes (e.g. methods), then manual 0 assignment will be required and the whole point of the scoped_handle in this case is missed. e.g.: int main() { int* i =0; { i = getNewInt(); stlsoft::scoped_handle<int*> fgdet(i, releaseIntAndReset); // release i, but not set i to 0 } int j = (int)i; // j != 0; } Of course, I can use the internal handle directly, but this is not always possible, and makes readability slightly harder.Seems like a hasty implementation on my part. I think the better solution is to ensure that the external resource handle is "null'd". I worked it out this morning (on my bike <g>), and have just to find a time to implement it. Basically, I'll add a union that holds a "H h" and a "H* ph". The scoped_handle will hold onto an instance of that, and a marker to say which is viable. The function translators will know which member to use anyway (translate() will use the h member; translate_indirect will use the ph member). It's time for a beta 44 anyway. Just busy beavering with the last few issues on XSTLv1 - have so far chopped 600 pages to 545, and hope to get down to 500 - so it might be a day or two until I can do the STLSoft beta. btw, this'll also be properly "rooted" - i.e. all will be below /stlsoft-1.9.1-beta44/ - as I've recently done to several other projects. I'm starting to toe the OS line ... ;-) Once the book's sent off I will do STLSoft 1.9.1 proper. All that's really wanting is the docs and the website. So please keep sending in your documentation criticism. Cheers Matthew
Jan 31 2007
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type"> </head> <body dir="ltr" bgcolor="#ffffff <br> <blockquote cite="mideprcar$2bo4$1 digitaldaemon.com" type="cite"> <pre wrap="">Seems like a hasty implementation on my part. I think the better solution is to ensure that the external resource handle is "null'd". I worked it out this morning (on my bike <g>), and have just to find a time to implement it. Basically, I'll add a union that holds a "H h" and a "H* ph". The scoped_handle will hold onto an instance of that, and a marker to say which is viable. The function translators will know which member to use anyway (translate() will use the h member; translate_indirect will use the ph member). </pre> </blockquote> Hmmm..<br> That'll work and, indeed, fix the problem.<br> <br> However, I am concerned (from your point of view) that this would make 2 scoped_handle classes, with 2 subtly different behaviors.<br> <br> Ideally the union should (impossibly?) detect if the class was constructed with an externally held handle e.g. <br> <br> <pre> FILE *file = ::fopen("file.ext", "r"); // ... { ::stlsoft::<b>scoped_handle</b><FILE*> h2(file, ::fclose); // ... } // ... </pre> or used with the internally held handle e.g. <br> <br> <tt>::stlsoft::<b>scoped_handle</b><int> h1(::open("file.ext"), ::close);<br> <br> </tt><br> What would happen if I used an indirect function, with a reference to a temporary?<br> Can this happen? <br> Can the scope of the <tt><b>scoped_handle<> </b></tt>exceed the scope of the given temporary ?<br> <br> Something like this:<br> <br> <tt>// </tt><tt>MyClass </tt><tt>ctor<br> MyClass(): <br> myScopedHandle(makeHandle(), ::releaseAndReset) // init </tt><tt>myScopedHandle handle with indirect function<br> {}<br> </tt><tt><br> </tt>Can this happen?<br> <tt>makeHandle() </tt>will generate a temp handle, and <tt>myScopedHandle </tt>will hold a reference to it. When the ctor goes out of scope, what happens to the temp reference? (I'm not so clear about temp rules at the moment).<br> In this case, it seems that a copy need to be made, not a reference.<br> <br> Confused,<br> Adi<br> <br> <br> <br> <br> <br> </body> </html>
Feb 01 2007
charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable You're right. I'd already considered this, and so decided that the = "nulling" ctor overload would take an address of the handle. This has = the big advantage that there can be no such confusion, and the small = disadvantage that you can't "inline" the allocation function invocation = with the scoped_handle ctor. ;-) This should all work ticketyboo (LOL, don't you love the silly English = and our daft expressions!). Just give me a few days to get over the last = book push. BigBoy "Adi Shavit" <adish gentech.co.il> wrote in message = news:epsgtf$hve$1 digitaldaemon.com... Seems like a hasty implementation on my part. I think the better = solution is to ensure that the external resource handle is "null'd". I worked it out this morning (on my bike <g>), and have just to find a time to implement = it. Basically, I'll add a union that holds a "H h" and a "H* ph". The scoped_handle will hold onto an instance of that, and a marker to say = which is viable. The function translators will know which member to use anyway (translate() will use the h member; translate_indirect will use the ph member). Hmmm.. That'll work and, indeed, fix the problem. However, I am concerned (from your point of view) that this would make = 2 scoped_handle classes, with 2 subtly different behaviors. Ideally the union should (impossibly?) detect if the class was = constructed with an externally held handle e.g.=20 FILE *file =3D ::fopen("file.ext", "r"); // ... { ::stlsoft::scoped_handle<FILE*> h2(file, ::fclose); // ... } // ... or used with the internally held handle e.g.=20 ::stlsoft::scoped_handle<int> h1(::open("file.ext"), ::close); What would happen if I used an indirect function, with a reference to = a temporary? Can this happen?=20 Can the scope of the scoped_handle<> exceed the scope of the given = temporary ? Something like this: // MyClass ctor MyClass():=20 myScopedHandle(makeHandle(), ::releaseAndReset) // init = myScopedHandle handle with indirect function {} Can this happen? makeHandle() will generate a temp handle, and myScopedHandle will hold = a reference to it. When the ctor goes out of scope, what happens to the = temp reference? (I'm not so clear about temp rules at the moment). In this case, it seems that a copy need to be made, not a reference. Confused, Adi
Feb 01 2007
You're right. I'd already considered this, and so decided that the "nulling" ctor overload would take an address of the handle. This has the big advantage that there can be no such confusion, and the small disadvantage that you can't "inline" the allocation function invocation with the scoped_handle ctor. ;-)Actually, I'm not sure I understand what you mean. The problem I mentioned was specifically related to and assumed taking a reference. Do you mean something like taking a reference as opposed to taking a const reference to not compile (or select another ctor) when a temp is given?This should all work ticketyboo (LOL, don't you love the silly English and our daft expressions!). Just give me a few days to get over the last book push. BigBoyYou're in a good mood :-). Adi
Feb 01 2007
charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable He he. I'm failing to communicate by trying to be terse. (Time is tres = short this week.) Basically, under my projected change, if you use a non-nulling release = fn, you can call like this: scoped_handle<void*> sh(::malloc(10), ::free); or this: void *pv =3D ::malloc(10); scoped_handle<void*> sh(pv, ::free); If you're using a nulling release func, then you must call it like this: void free_set_null(void **); void *pv =3D ::malloc(10); scoped_handle<void*> sh(&pv, free_set_null); Note that you will pass &pv, not pv, in the second case. In other words, = you pass a pointer to your variable. That way, all issues of = const/non-const / temp/non-temp just disappears. The "cost" is just that = we will remove the (recently added) ability to write: scoped_handle<void*> sh(::malloc(10), free_set_null); I'm of the opinion that that cost is worth paying. Thoughts? As for my mood, well, I'm nearing the point where the final draft of = XSTLv1 will be dispatched to the publishers - just tidying up, and = waiting for cover quotes from reviewers ... - my boys (Bob luv 'em) are = both back at school - so I can concentrate a bit better - and I have had = very fruitful discussions with my editor about getting XSTLv2 trimmed = down and therefore likely to be written in half the time I expected. :-) "Adi Shavit" <adish gentech.co.il> wrote in message = news:45C24A13.9010603 gentech.co.il... You're right. I'd already considered this, and so decided that the = "nulling" ctor overload would take an address of the handle. This has = the big advantage that there can be no such confusion, and the small = disadvantage that you can't "inline" the allocation function invocation = with the scoped_handle ctor. ;-) Actually, I'm not sure I understand what you mean. The problem I mentioned was specifically related to and assumed taking = a reference. Do you mean something like taking a reference as opposed to taking a = const reference to not compile (or select another ctor) when a temp is = given? This should all work ticketyboo (LOL, don't you love the silly = English and our daft expressions!). Just give me a few days to get over = the last book push. BigBoy You're in a good mood :-). Adi
Feb 01 2007
charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable I've implemented this now, and it works fine. I'll include this in the = next beta. "Matthew Wilson" <matthew hat.stlsoft.dot.org> wrote in message = news:eptn32$22tc$1 digitaldaemon.com... He he. I'm failing to communicate by trying to be terse. (Time is tres = short this week.) Basically, under my projected change, if you use a non-nulling release = fn, you can call like this: scoped_handle<void*> sh(::malloc(10), ::free); or this: void *pv =3D ::malloc(10); scoped_handle<void*> sh(pv, ::free); If you're using a nulling release func, then you must call it like = this: void free_set_null(void **); void *pv =3D ::malloc(10); scoped_handle<void*> sh(&pv, free_set_null); Note that you will pass &pv, not pv, in the second case. In other = words, you pass a pointer to your variable. That way, all issues of = const/non-const / temp/non-temp just disappears. The "cost" is just that = we will remove the (recently added) ability to write: scoped_handle<void*> sh(::malloc(10), free_set_null); I'm of the opinion that that cost is worth paying. Thoughts? As for my mood, well, I'm nearing the point where the final draft of = XSTLv1 will be dispatched to the publishers - just tidying up, and = waiting for cover quotes from reviewers ... - my boys (Bob luv 'em) are = both back at school - so I can concentrate a bit better - and I have had = very fruitful discussions with my editor about getting XSTLv2 trimmed = down and therefore likely to be written in half the time I expected. :-) "Adi Shavit" <adish gentech.co.il> wrote in message = news:45C24A13.9010603 gentech.co.il... You're right. I'd already considered this, and so decided that the = "nulling" ctor overload would take an address of the handle. This has = the big advantage that there can be no such confusion, and the small = disadvantage that you can't "inline" the allocation function invocation = with the scoped_handle ctor. ;-) Actually, I'm not sure I understand what you mean. The problem I mentioned was specifically related to and assumed = taking a reference. Do you mean something like taking a reference as opposed to taking a = const reference to not compile (or select another ctor) when a temp is = given? This should all work ticketyboo (LOL, don't you love the silly = English and our daft expressions!). Just give me a few days to get over = the last book push. BigBoy You're in a good mood :-). Adi
Feb 01 2007
Got it! Makes perfect sense. Thanks. Sounds good. Adi Matthew Wilson wrote:He he. I'm failing to communicate by trying to be terse. (Time is tres short this week.) Basically, under my projected change, if you use a non-nulling release fn, you can call like this: scoped_handle<void*> sh(::malloc(10), ::free); or this: void *pv = ::malloc(10); scoped_handle<void*> sh(pv, ::free); If you're using a nulling release func, then you must call it like this: void free_set_null(void **); void *pv = ::malloc(10); scoped_handle<void*> sh(&pv, free_set_null); Note that you will pass &pv, not pv, in the second case. In other words, you pass a pointer to your variable. That way, all issues of const/non-const / temp/non-temp just disappears. The "cost" is just that we will remove the (recently added) ability to write: scoped_handle<void*> sh(::malloc(10), free_set_null); I'm of the opinion that that cost is worth paying. Thoughts? As for my mood, well, I'm nearing the point where the final draft of XSTLv1 will be dispatched to the publishers - just tidying up, and waiting for cover quotes from reviewers ... - my boys (Bob luv 'em) are both back at school - so I can concentrate a bit better - and I have had very fruitful discussions with my editor about getting XSTLv2 trimmed down and therefore likely to be written in half the time I expected. :-) "Adi Shavit" <adish gentech.co.il <mailto:adish gentech.co.il>> wrote in message news:45C24A13.9010603 gentech.co.il...You're right. I'd already considered this, and so decided that the "nulling" ctor overload would take an address of the handle. This has the big advantage that there can be no such confusion, and the small disadvantage that you can't "inline" the allocation function invocation with the scoped_handle ctor. ;-)Actually, I'm not sure I understand what you mean. The problem I mentioned was specifically related to and assumed taking a reference. Do you mean something like taking a reference as opposed to taking a const reference to not compile (or select another ctor) when a temp is given?This should all work ticketyboo (LOL, don't you love the silly English and our daft expressions!). Just give me a few days to get over the last book push. BigBoyYou're in a good mood :-). Adi
Feb 02 2007
"Adi Shavit" <adish gentech.co.il> wrote in message news:epv15g$1175$1 digitaldaemon.com...Got it! Makes perfect sense. Thanks. Sounds good. AdiStill going to be a while before I can do STLSoft release, so am including new scoped_handle here. No guarantees on its quality. Matty begin 666 scoped_handle.zip M<'#M76USVSB2_CY5^0\=3Y5+\LJRG<SL[LB.=Q6)CG G2SJ2CC=UN6+1(F2Q MAB*Y)&6?:S;WVZ\;(/ F2I;?8L<KI&8LD4!WH[OQH$&TP+T=V'NL\N8GV($3 MQV4M2$H4NY$_B?>BF17&01SN16,_8+8YM3S;9<UI$$"-7?GN%;-A$OHS..UK M+!K%87/: %9+O_%8Y$1Z;->)-J<_FH>!'R4L"N1 %P(KM&8L9J$361=X16NK MS2Y8" >__?8+KW(6V%F5=YX-)^PBG",7>+>__Y>4DH%2_AY![%/%MNV /K6N MG+C!)0O9/^<LBAWO$N(I`\>SG9"-8YC,O7'L^)[E.O%-2JKGSS(=3^,X:.WM M):IN^N'E7B:]']R$SN4TAMJXSB7>)9D:<&K%R.<:SAULY0'J#Q)E XY4KJV0 M<0)MUP5.("(-L1 -E>E&8[83Q:%S,2<1.9%Y1,)#HDNZ<N%XI KLY"QJP+43 M3P'[2W_]><S)S'S;F3ACBX TT$8,`A;.G!AU"D'H7SDV?HBG5LQ5,_%=U[\F M18U]U!(UBG CM'LK%6VW)%P$_D1*-?9MK#U'6X8LME!:(FM=H%WQEM27Y\?. MJRR0]-+VQ_,9\V*NZX0>MMM#B_AX/X2918/'<J-,\]QDO'&N&[)S`^;P=G3? M" R&!O354]7 :L:P08PYM<6F,#R!4T7K]/!K^Z/:5XTOG.>): R(WPDR;,.H MK1EJYZS?UF!TIHV&NB!'7>RJ>J??5D^5;A.E0,Z ?%8&!NB]=K]?ZO'P?*!H MAL,NU[VN:)_5CJ(?0G^H<^6=Z4H#N1AM MR%"' SJ:_ARUA'IH8_,N5_APP+N-"AMJ7X PZ8/;HP'G/06OH^4'LH>&UB:5 MFPZE$Q]S3MW ! ;U!-K=SRJ)+RIS<N :NIJX$5[6SSJ]Q 39$+D],EBGP [. M6_1O;V<'ODXPC% C?$AE^'H1.FP"_]WYTY_ ]]R;_X$NFS >QT9")$*:A%RK M50P;./4$+ +?\1 !DY A9K/ 141,;M:^ALCB,O3G 6FZS 5%$J;)FYM)PPBV M)H[E;A_M\;--?6)W;[C(LXNC \9&F_S7U/]3Q38X*/$+UH42'_3L-=B8I^W_ M3*R\]]B1M>J-W;G-HO7\J"<_D0X<T12.TA&51(O3X\K.55-ZJHYU_%F PQWG M?>I[$%J7,TO2K 7S:%JON&XG2X86_'+PVT$]KY:QE.^)^C^ ""BPQFS!LJD- M!D-ST#Y5]%&[ \/9DPTDI+WYZ8^\P)7-GLQZ!)4KO'(5TKSY24(LNF9DTMJ+ M^F;R=9SY._30/3'HQ. .>N;4=S' XUTE6\\]$<-B2:Y0Z=&*Z+#X?2>05[Y! M5N;)-0PV,9:^\'T7X"*![4,2C3=/N-9Z0%XCV[;2FK4)!LNLOB 'Q9V[Q_/F M%#ZD M?O<`O8%\CCM* +YGCJTH/BI4/*XAK50L*K+_;1TC<Z/V=MJ4OB8[G*^%T*9C M3%"E8\M];,Q8%QQD]^^!#UG3AT,$E0U,;&#B MA)0HMI\149+.WP-0TI8;/-G R6O'DP6,2!\^W X6=UN-F&2_'V%)0H)D*JT> MJL\Z-!_96YXJ/+US[/D4'O+ `/3?W!N>)0JY:XCQG(ZS+,[8^,T=9YO[[2TD MB5+^ >.A-WIC)I)%^,Z Y7)Z//'(RN EVX(RG\*R;;S%$T L3JT687=<MIM* M54]U++VI`18E>B3Y*%\IXP0_MEK5.Y!'7%2,H:?O:ZW6C*N\=K"_7Z<<J$G( M&'G95W23A(Y0DA^N2Q[5P0/TZ0&2QQL>NKWCLB;[WWB+\QB[?K0F$](PK"H[ M?.?V`TE>8M6 K7"+#YBEDG+[D2+>U: 9[_]RX;YZE/UA4(:'V*\-Y$A =BST M4)$WNWE+.[/9/*9=GEV>&%:+&(.(<8MQ N^;OY*9U5G P FE7V&(=2 3K!QY MCO14&%M>`D01$QO4./($(VPE$G8DOR;T_&MVQ4)*66(A'S86XA ?K<COBGD. M(Z(\.PLF5BA&1I2O;K/8&D]K=<JEFOIV`ZZGSGA*<N0S<,C9P^(03!-NJCM" M74PV'YR82' EH'F2-*X8[95MCZ?SY+(=(6'L N?P:7 / ^*O5!L, C-QX>^K MY\>[38[YYE6KW^*JMS"5<N$$8!ME]"H1KAA5LKHD74$Q :WUZ(G**Z )V^'( MX="?)% LTBX.7Z$);AY)FIN KVDSZW2D^_-QEQI):HLV?=\N[/J>X-1]^E'1 M3(/G!QF*V3&&FIQ3Z_"O?\E-X'6;#C\K6G_8[IJ4\:2II^H`;W7K"^I(Q5TU M4UAB#MC-30(B<XY[6>+\F?X*>JN5[$OV>9-&&;+0DRD9TLFRL*:KUPJ4ZM5D M%K -YJZ+F+U?V(R<F=-I+;\_V:!+5+7&_U^Z$V,XM+UT'7S4$S/R<:N51H(E MGM;<V5^\+,GW43UG)W DW]EYN/,$3^D]Z:.PU^%&%<N 6S"/(.]^&+<JN^86 MBW4D> 2X?6)7>FV8"\\0WL)SQ+=+G?ZEA;H_$,YN`MY[ .S+BWV7>]P+"7^7 M^MSK1>.[A,"5 ?/23?&J +EB5_P5Q,O)?OSS1#G93OQ+1/%$-9M ^78<?U0O MNOM3X*5^]$*P>84G;6+E'S567N+S+RU4_F$P=A,HWQU 7UZ<_ -!\29*7B]* MZG1H3IKC,[6N6$;&<D-FV732#O-X: ZSQ<W_*_KW^K9!P:S0L;PX;YBRZE>E M6Y+C%!,NG4GM+8[)^*96S[E83A8JPG')V1LI"7GO6VK<JKR4=BQ.'2JD#BW) MX5'1R&/TW BNIRP]`BG->*)$()& Y>UN>7-"'6E$08K_WCSIRY*?:W]'Q2;0 M=XFCDX0UKRQWSDR4[,,'#AM-_K/RPY7:&P8TG%&$-;37(7\4/IO MC.;,=M! MQB RU OC**N^VIP+0S1WOD(EA(W'B/=^N,883-/&R2(7E!1=#J6*+ !=G]' M0;K2S+52TB3L72W'*3_G<VD:<2[7%\J%NGJX<'6Q[.V]/2HD[_J5<9] R'NT M`"^BR XMY924E"'7$S]ZE!B2ZA(9!*_R8Z)\J>WP2:J>_PDJ;"__!6K],&.; M0FNVG$BO"<Y+?QT$P,'V3FJUQO'<<K/1$HKP.L>RRO #GT]_%RS[F0M%P]5N M4 R/,[]/S+4MG3UW9]OGH1)V_<.2!E(J\<M$(5TIUYH_!$N>LM_AO"59*UV_ M) <OJGI;5*E(KI>\_O >*?;W3)JO<MC"4#FLI"C'W5KT1.45U.Z5-,^5NTF: M"I_X;O(S;]DU>5A:W7KY<H_CJ(4S#EXK=FY2V[X;D#ZYB[Y&.-TD^[R89)^U MLB\>QZ_SAX1LD'>3*/$PX'UB_]S [DK8?<6[QPGMU4]B7]C&;/H067K^:NE_ MS(W1.^U6%G?9Q1VI'/ `=)IY[OYF;[* R&6JVFSQ+=WB2]3S6-W]#MMD]]MC MPKF;\,B,8;'DX*?BKBA\(Z0:$<MHSQ&"X[<CJ.8P8DE)-X)>QL[/*]OU>1'O MG(FNK2 0:% ZG FJ#S',':6,,:;CN?3N'>Y$1*JV<%[0MCN-&HO'"&V'TZB> MONH#ZS1Y MLR3)(*&3EX<^H#AE:JU6;I=J?;:5R0A_2( 3F2?IWOVW)W&U,PRW=V/Q$LS4 MW4I/%<X&JF$H>N&=1EO-O;E'[^^+XN+[P4QYV6Q.MZHB:TGML0=/Z44X2U[B M\PVYB9<?%M_DL_9K?%1QF!Q_ER'"W9 CDZO0]QR$<;H[:(X6R&J?Z:7HOVE MN4\!/+-"UT'[(A"?.][[=PVX9ES]&-*P2Q[#X/S&0EK^)+,EKM0R.>4Q;4NV MW &O$LRB/XNX):QC>I'Y3YQ;BJ.IG .RV^L)9",NN1BPC'!T[5N%C]B%A257 M`` `Q7E"-MJVFG3C$0``OWD``!$``````````0` `+:!`````'-C;W!E9%]H ?86YD;&4N:'!P4$L%! `````!``$`/P```!(2```````` ` end
Feb 02 2007