pg.ddx.io  pgsql-interfaces@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: Joe Conway <mail@joeconway.com>
To: James Orr <james@lrgmail.com>
Cc: Tom Lane <tgl@sss.pgh.pa.us>
Cc: pgsql-interfaces@postgresql.org
Subject: Re: bytea on windows perl client
Date: Thu, 18 Jul 2002 10:21:36 -0700
Message-ID: <3D36F920.7010005@joeconway.com> (raw)
References: <200207171201.25600.james@lrgmail.com>
	<200207171300.01423.james@lrgmail.com>
	<3D35A401.1090301@joeconway.com>
	<200207181301.35572.james@lrgmail.com>

James Orr wrote:
> On Wednesday 17 July 2002 13:06, Joe Conway wrote:
> 
>>>\211PNG\015\012\000 and so on.
>>
>>This is the escaped output form of bytea. It seems that on linux the
>>perl script is either using a binary cursor, or automagically unescaping
>>the output, while on windows it isn't. I'm not sure why that would
>>happen, but hopefully one of the perl gurus hanging around will chime in.
>>
>>Joe
> 
> 
> OK, I really need a solution to this quite quickly.  It's a simple enough 
> script (posted earlier) so if this is something I cannot do with DBD::Pg on a 
> windows platform I can do it with something else.  If that's the case what's 
> the best thing to do it with?  PHP?  I don't have control of the IIS server 
> they are running this on and I doubt very much they have PHP running on it.
> 
> Is the only way to connect to postgres with ASP via the ODBC driver?  How will 
> that handle the bytea field?

I really have to believe a relatively simple solution exists in perl -- 
I'm just not familiar enough with perl to help. Did you see my post on 
PHP's stripcslashes()? I'd look for the equiv function in perl.

The ASP/ODBC approach will have the same issue because the standard 
output format of bytea is octal escaping for all non-printable characters.

A quick search on google finds:
Data: Numbers
   Why isn't my octal data interpreted correctly?

     Perl only understands octal and hex numbers as such when they
     occur as literals in your program. If they are read in from
     somewhere and assigned, no automatic conversion takes place.
     You must explicitly use oct() or hex() if you want the values
     converted. oct() interprets both hex ("0x350") numbers and
     octal ones ("0350" or even without the leading "0", like
     "377"), while hex() only converts hexadecimal ones, with or
     without a leading "0x", like "0x255", "3A", "ff", or
     "deadbeef".

     This problem shows up most often when people try using
     chmod(), mkdir(), umask(), or sysopen(), which all want
     permissions in octal.

         chmod(644,  $file); # WRONG -- perl -w catches this
         chmod(0644, $file); # right

So maybe you could replace all single "\" characters (but *not* "\\") 
with "0" and then use oct()?


FWIW, here is the C code for the PHP stripcslashes() function. Maybe you 
can convert this to a perl function and use it.

/* {{{ php_stripcslashes
  */
PHPAPI void php_stripcslashes(char *str, int *len)
{
	char *source, *target, *end;
	int  nlen = *len, i;
	char numtmp[4];

	for (source=str, end=str+nlen, target=str; source<end; source++) {
		if (*source == '\\' && source+1<end) {
			source++;
			switch (*source) {
				case 'n': *target++='\n'; nlen--; break;
				case 'r': *target++='\r'; nlen--; break;
				case 'a': *target++='\a'; nlen--; break;
				case 't': *target++='\t'; nlen--; break;
				case 'v': *target++='\v'; nlen--; break;
				case 'b': *target++='\b'; nlen--; break;
				case 'f': *target++='\f'; nlen--; break;
				case '\\': *target++='\\'; nlen--; break;
				case 'x': if (source+1<end && isxdigit((int)(*(source+1)))) {
						numtmp[0] = *++source;
						if (source+1<end && isxdigit((int)(*(source+1)))) {
							numtmp[1] = *++source;
							numtmp[2] = '\0';
							nlen-=3;
						} else {
							numtmp[1] = '\0';
							nlen-=2;
						}
						*target++=(char)strtol(numtmp, NULL, 16);
						break;
					}
					/* break is left intentionally */
				default: i=0;
					while (source<end && *source>='0' && *source<='7' && i<3) {
						numtmp[i++] = *source++;
					}
					if (i) {
						numtmp[i]='\0';
						*target++=(char)strtol(numtmp, NULL, 8);
						nlen-=i;
						source--;
					} else {
						*target++=*source;
						nlen--;
					}
			}
		} else {
			*target++=*source;
		}
	}

	if(nlen != 0) {
		*target='\0';
	}

	*len = nlen;
}
/* }}} */


HTH,

Joe




view thread (10+ messages)

Message-ID: <3D36F920.7010005@joeconway.com>
Permalink:  ../3D36F920.7010005@joeconway.com/
Also on:    postgresql.org/message-id/3D36F920.7010005@joeconway.com

 · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-interfaces@postgresql.org
  Cc: mail@joeconway.com, james@lrgmail.com, tgl@sss.pgh.pa.us
  Subject: Re: bytea on windows perl client
  In-Reply-To: <3D36F920.7010005@joeconway.com>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox