Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

CGI script bringing its own data

by hacmac (Novice)
on Sep 03, 2003 at 09:31 UTC ( [id://288557]=perlquestion: print w/replies, xml ) Need Help??

hacmac has asked for the wisdom of the Perl Monks concerning the following question:

Hi everyone!
 
This is my first posting on here. I just wasn't able to find the right terms to feed a search engine with. Sorry if my answer is too stupid or something.
 
Suppose there's a CGI script that shall output a PNG graphic, like this:
 
#!/usr/bin/perl use strict; use GD; my $infile = "/opt/apache/icons/apache_pb.png"; my $data; open (my $in_fh, $infile) or die; while (<$in_fh>){ $data .= $_; } close $in_fh; my $image = GD::Image->newFromPngData($data, 1); print "content-type: image/png\n\n"; print $image->png;

 
In reality, I'm going to draw a few annotations onto the PNG, using the GD library.
 
What I'd like to accomplish is that the script should bring its own data, without having to do a read operation, the path to the file needing to be configured, and needing to catch open errors in a more graceful way than I did in my example.
 
How would I encapsulate my data in the script?
 
Thanks in advance everyone!

Replies are listed 'Best First'.
Re: CGI script bringing its own data
by liz (Monsignor) on Sep 03, 2003 at 09:47 UTC
    What I gather from your question is that you want to make the result of:
    my $image = GD::Image->newFromPngData($data, 1);
    be available automagically when the script starts.

    There are several ways to do that:

    • If you can use mod_perl, make sure that $image gets initialized at server startup time.
    • other ways of unfreezing data

    I haven't tried it myself, but I fear that you'll not be able to freeze the GD::Image object (because it is most likely a complex object, not a simple hash ref), so you would have to freeze $data. But that's just the contents of the file, so that doesn't make much sense.

    You can however speed up the reading of the original PNG file:

    open (my $in_fh, $infile) or die; local $/; # enable slurping mode my $data = <$in_fh>; close $in_fh;

    Hope this helps.

    Liz

      Thanks for your advice, Liz. Freezing $data would indeed make sense to me, as having the data at hand without reading it from a file is what I'm trying to do. I initially thought about useing Storable, but that would still leave a file for loading and really wouldn't make any sense. Basically, I'd like to do the following: Instead of
      open (my $in_fh, $infile) or die; local $/; # enable slurping mode my $data = <$in_fh>; close $in_fh;
      I'd like to do
      my $data = handoverthedata(); (...) sub handoverthedata{ # Inlined data starts here # and gets stored in my $foo... # Data # Data # Data # Data # Data # Data # Data # Data # Data # Data # Data # Data # Data return $foo; }
      Any ideas on how to do it? I think I've seen similar constructs in C (though I don't know any C), and I'd be surprised if there wasn't a "canonical" way to do it in Perl. -hacmac
        But why would you want it to do that? It's not going to help you much.

        But anyway, maybe the following will do the trick if you only have one file:

        1. add a line with __DATA__ at the end of your script.
        2. save the script and make sure the editor doesn't keep it open
        3. then in the shell, do a "cat pngfilename >>yourscript" (assuming you have a *nix here. If you have Win32, it might work in a command window by replacing "cat" with "type")
        4. open the script again, you should see a lot of garbage at the end, don't touch that.
        5. Remove the open() and close() calls.
        6. replace my $data = <$in_fh>; with my $data = <DATA>;

        I haven't tried it myself. I hope your editor doesn't mangle the data. If it does, then keep a clean copy without the data at the end and create a final copy each time you made changes.

        Hope this helps.

        Liz

Re: CGI script bringing its own data
by Skeeve (Parson) on Sep 03, 2003 at 11:41 UTC
    I used to do it like this:
    print getData('ThisScript'); print getData('ls-l'); sub getData { my($name)= '[' . (shift) . ']'; my($data, $hit); seek(DATA,0,0); while (<DATA>) { chomp; if ($hit= ($name eq $_) ... /^\[/) { next if $hit<2; last if $hit=~ /e0/i; $data.=unpack('u',$_); } } return $data; } # to create data do # cat FILE | perl -e 'print pack ("u",join("",<>))' >> SCRIPT __DATA__ [ThisScript] M<')I;G0@9V5T1&%T82@G5&AI<U-C<FEP="<I.PIP<FEN="!G971$871A*"=L M<RUL)RD["G!R:6YT(&=E=$1A=&$H)U1H:7-38W)I<'0G*3L*<')I;G0@9V5T M1&%T82@G;',M;"<I.PH*<W5B(&=E=$1A=&$@>PH@(&UY*"1N86UE*3T@)ULG M("X@*'-H:69T*2`N("==)SL*("!M>2@D9&%T82P@)&AI="D["B`@<V5E:RA$ M051!+#`L,"D["B`@=VAI;&4@*#Q$051!/BD@>PH@("`@8VAO;7`["B`@("!I M9B`H)&AI=#T@*"1N86UE(&5Q("1?*2`N+BX@+UY<6R\I('L*("`@("`@;F5X M="!I9B`D:&ET/#(["B`@("`@(&QA<W0@:68@)&AI=#U^("]E,"]I.PH@("`@ M("`D9&%T82X]=6YP86-K*"=U)RPD7RD["B`@("!]"B`@?0H@(')E='5R;B`D M9&%T83L*?0H*(R!T;R!C<F5A=&4@9&%T82!D;PHC(&-A="!&24Q%('P@<&5R M;"`M92`G<')I;G0@<&%C:R`H(G4B+&IO:6XH(B(L/#XI*2<@/CX@4T-225!4 +"@I?7T1!5$%?7PH` [ls-l] M=&]T86P@,CDS,@HM<G<M+2TM+2TM("`@,2!U<V5R('-T869F("`@("`@("`U M-C@@4V5P("`S(#$S.C`Y(&1E860N;&5T=&5R"F1R=W@M+7@M+7@@("`V('5S M97(@<W1A9F8@("`@("`@(#4Q,B!397`@(#,@,3$Z-#$@9&]W;FQO860*+7)W M+2TM+2TM+2`@(#$@=7-E<B!S=&%F9B`@("`@-CDQ-S4P(%-E<"`@,B`P-SHU M,2!D<V-F,C<R-2YJ<&<*9')W>"TM+2TM+2`@(#,@=7-E<B!S=&%F9B`@("`@ M("`@-3$R(%-E<"`@,R`Q,SHR-2!-86EL"F1R=RTM+2TM+2T@("`R('5S97(@ M<W1A9F8@("`@("`@(#4Q,B!!=6<@,3$@,3`Z,SD@;G-M86EL"BUR=RTM+2TM M+2T@("`Q('5S97(@<W1A9F8@("`@("`@(#$W.2!397`@(#(@,3(Z,C$@;W!E M;E]Q=65S=&EO;G,*+7)W+7(M+7(M+2`@(#$@=7-E<B!S=&%F9B`@("`@("`@ M.3`P(%-E<"`@,B`P.3HS,R!P<F]F:6QE"F1R=RTM+2TM+2T@("`S('5S97(@ M<W1A9F8@("`@("`@(#4Q,B!*=6P@,C@@,3$Z,C0@<'5B;&EC7VAT;6P*9')W M>'(M>'(M>"`@(#(@=7-E<B!S=&%F9B`@("`@("`Q,#(T(%-E<"`@,B`Q,3HT M-"!354X*+7)W+2TM+2TM+2`@(#$@=7-E<B!S=&%F9B`@("`@("`Q,3`W(%-E M<"`@,R`@,C`P,R!X"BUR=RTM+2TM+2T@("`Q('5S97(@<W1A9F8@("`@(#<W 8,S0W-B!397`@(#,@,3(Z-#0@>"YS=V8* [END]
      Absolutely! That's exactly what I've been looking for, and my first proof of concept script works like a charm.
       
      I had read about those pseudo file handles somewhere, but hadn't been able to make sense of it.
       
      Thanks a lot to you and everyone!
       
      -hacmac
Re: CGI script bringing its own data
by Abigail-II (Bishop) on Sep 03, 2003 at 09:45 UTC
    You could include the entire content of the PNG file as a single string in your program. Just make sure you escape the delimiters. Or you could uuencode the PNG file and include that as a string.

    Personally, I'd leave the PNG file as a separate file.

    Abigail

      Thanks for your advice. I really believe it's a Good Thing(tm) to bring the icons (see, it's not unbelievable amounts of data) inside the script, because there are less things to go wrong. Uuencoding might be an option. Is there a more "canonical" way to do it? I know, tmtowtdi, but I don't want people to look at my script and think "gee, what a moron". ;-) -hacmac
        I doubt there's a canonical way of doing it in Perl, as I've never seen or heard about any program doing so. In C program, you seem sometimes small images imbedded by defining an appropriate array with byte values.

        Abigail

Re: CGI script bringing its own data
by benn (Vicar) on Sep 03, 2003 at 11:00 UTC
    I believe you're looking for the __DATA__ filehandle. Stick it at the end of your code, and you can treat it just as if you'd opened a regular file.
    while (<DATA>) { # do stuff with $_ } # ...or a slurp seek(DATA,0); my $data = (<DATA>); # end of script __DATA__ # Data # Data # Data
    Cheers, Ben.
Re: CGI script bringing its own data
by Taulmarill (Deacon) on Sep 03, 2003 at 12:15 UTC
    the Official GD documentation gives one example that should do what you want.
    open (PNG,"barnswallow.png") || die; $myImage = newFromPng GD::Image(\*PNG) || die; close PNG;

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://288557]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others romping around the Monastery: (3)
As of 2024-03-19 10:19 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found