src/ai/paraFlow/runtime/fileLib.c 1.21

1.21 2009/10/20 22:32:01 galt
keep http request together
Index: src/ai/paraFlow/runtime/fileLib.c
===================================================================
RCS file: /projects/compbio/cvsroot/kent/src/ai/paraFlow/runtime/fileLib.c,v
retrieving revision 1.20
retrieving revision 1.21
diff -b -B -U 1000000 -r1.20 -r1.21
--- src/ai/paraFlow/runtime/fileLib.c	8 Mar 2006 01:46:20 -0000	1.20
+++ src/ai/paraFlow/runtime/fileLib.c	20 Oct 2009 22:32:01 -0000	1.21
@@ -1,436 +1,436 @@
 /* print - Implements print function for variable types. */
 #include "common.h"
 #include "dystring.h"
 #include "../compiler/pfPreamble.h"
 #include "pfString.h"
 #include "net.h"
 
 void _pf_prin(FILE *f, _pf_Stack *stack, boolean quoteString);
 /* Print out single variable where type is determined at run time. */
 
 void _pf_getObj(FILE *f, _pf_Stack *stack);
 /* Read in variable from file. */
 
 struct file
     {
     int _pf_refCount;			     	/* Number of references. */
     void (*_pf_cleanup)(struct file *obj, int id); /* Called when refCount <= 0 */
     _pf_polyFunType *_pf_polyFun;	/* Polymorphic functions. */
     struct _pf_string *name;		/* The only exported field. */
     FILE *f;				/* File handle. */
     struct dyString *dy;			/* Buffer for reading strings. */
     };
 
 static void fileCleanup(struct file *file, int typeId)
 /* Clean up string->s and string itself. */
 {
 carefulClose(&file->f);
 dyStringFree(&file->dy);
 _pf_class_cleanup((struct _pf_object *)file, typeId);
 }
 
 static FILE *mustFdopen(int fd, char *name, char *mode)
 /* fdopen a file (wrap FILE around it) or die trying */
 {
 FILE *f = fdopen(fd, mode);
 if (f == NULL)
     errnoAbort("Couldn't fdopen %s", name);
 return f;
 }
 
 static FILE *openUrlOrFile(char *spec, char *mode)
 /* If it's a URL call the fancy net opener, otherwise
  * call the regular file opener. */
 {
 if (startsWith("http://", spec) || startsWith("ftp://", spec))
     {
     int fd;
     if (mode[0] != 'r')
         errAbort("Can't open %s in mode %s", spec, mode);
     fd = netUrlOpen(spec);
     return mustFdopen(fd, spec, mode);
     }
 else
     return mustOpen(spec, mode);
 }
 
 static struct file *fileFromFILE(FILE *f, _pf_String name)
 /* Convert a FILE to a ParaFlow file. */
 {
 struct file *file;
 AllocVar(file);
 file->_pf_refCount = 1;
 file->_pf_cleanup = fileCleanup;
 file->name = name;
 file->f = f;
 file->dy = dyStringNew(0);
 return file;
 }
 
 void pf_fileOpen(_pf_Stack *stack)
 /* paraFlow run time support routine to open file. */
 {
 struct _pf_string *name = stack[0].String;
 struct _pf_string *mode = stack[1].String;
 struct file *file;
 
 _pf_nil_check(name);
 _pf_nil_check(mode);
 file = fileFromFILE(openUrlOrFile(name->s, mode->s), name);
 
 /* Remove mode reference. (We'll keep the name). */
 if (--mode->_pf_refCount <= 0)
     mode->_pf_cleanup(mode, 0);
 
 /* Save result on stack. */
 stack[0].v = file;
 }
 
 static _pf_String readAll(FILE *f)
 /* Return a string that contains the whole file. */
 {
 _pf_String string;
 char buf[4*1024];
 int bytesRead;
 string = _pf_string_new_empty(sizeof(buf));
 for (;;)
     {
     bytesRead = fread(buf, 1, sizeof(buf), f);
     if (bytesRead <= 0)
         break;
     _pf_strcat(string, buf, bytesRead);
     }
 return string;
 }
 
 void pf_fileReadAll(_pf_Stack *stack)
 /* Read in whole file to string. */
 {
 _pf_String name = stack[0].String;
 _pf_String string;
 FILE *f;
 _pf_nil_check(name);
 
 f = openUrlOrFile(name->s, "r");
 string = readAll(f);
 carefulClose(&f);
 
 stack[0].String = string;
 if (--name->_pf_refCount <= 0)
     name->_pf_cleanup(name, 0);
 }
 
 void _pf_cm_file_readAll(_pf_Stack *stack)
 /* Read all of file. */
 {
 struct file *file = stack[0].v;
 _pf_nil_check(file);
 stack[0].String = readAll(file->f);
 }
 
 void _pf_cm_file_close(_pf_Stack *stack)
 /* Close file explicitly. */
 {
 struct file *file = stack[0].v;
 carefulClose(&file->f);
 }
 
 void _pf_cm_file_write(_pf_Stack *stack)
 /* paraFlow run time support routine to write string to file. */
 {
 struct file *file = stack[0].v;
 struct _pf_string *string = stack[1].String;
 
 mustWrite(file->f, string->s, string->size);
 
 /* Clean up references on stack. */
 if (--string->_pf_refCount <= 0)
     string->_pf_cleanup(string, 0);
 }
 
 void _pf_cm_file_writeByte(_pf_Stack *stack)
 /* Write a Byte to file. */
 {
 struct file *file = stack[0].v;
 mustWrite(file->f, &stack[1].Byte, sizeof(stack[1].Byte));
 }
 
 void _pf_cm_file_writeShort(_pf_Stack *stack)
 /* Write a Short to file. */
 {
 struct file *file = stack[0].v;
 mustWrite(file->f, &stack[1].Short, sizeof(stack[1].Short));
 }
 
 void _pf_cm_file_writeInt(_pf_Stack *stack)
 /* Write a Int to file. */
 {
 struct file *file = stack[0].v;
 mustWrite(file->f, &stack[1].Int, sizeof(stack[1].Int));
 }
 
 void _pf_cm_file_writeLong(_pf_Stack *stack)
 /* Write a Long to file. */
 {
 struct file *file = stack[0].v;
 mustWrite(file->f, &stack[1].Long, sizeof(stack[1].Long));
 }
 
 void _pf_cm_file_writeFloat(_pf_Stack *stack)
 /* Write a Float to file. */
 {
 struct file *file = stack[0].v;
 mustWrite(file->f, &stack[1].Float, sizeof(stack[1].Float));
 }
 
 void _pf_cm_file_writeDouble(_pf_Stack *stack)
 /* Write a Double to file. */
 {
 struct file *file = stack[0].v;
 mustWrite(file->f, &stack[1].Double, sizeof(stack[1].Double));
 }
 
 void _pf_cm_file_readByte(_pf_Stack *stack)
 /* Read a Byte from file. */
 {
 struct file *file = stack[0].v;
 mustRead(file->f, &stack[0].Byte, sizeof(stack[0].Byte));
 }
 
 void _pf_cm_file_readShort(_pf_Stack *stack)
 /* Read a Short from file. */
 {
 struct file *file = stack[0].v;
 mustRead(file->f, &stack[0].Short, sizeof(stack[0].Short));
 }
 
 void _pf_cm_file_readInt(_pf_Stack *stack)
 /* Read a Int from file. */
 {
 struct file *file = stack[0].v;
 mustRead(file->f, &stack[0].Int, sizeof(stack[0].Int));
 }
 
 void _pf_cm_file_readLong(_pf_Stack *stack)
 /* Read a Long from file. */
 {
 struct file *file = stack[0].v;
 mustRead(file->f, &stack[0].Long, sizeof(stack[0].Long));
 }
 
 void _pf_cm_file_readFloat(_pf_Stack *stack)
 /* Read a Float from file. */
 {
 struct file *file = stack[0].v;
 mustRead(file->f, &stack[0].Float, sizeof(stack[0].Float));
 }
 
 void _pf_cm_file_readDouble(_pf_Stack *stack)
 /* Read a Double from file. */
 {
 struct file *file = stack[0].v;
 mustRead(file->f, &stack[0].Double, sizeof(stack[0].Double));
 }
 
 static void mustFlush(struct file *file)
 /* Flush file or die trying */
 {
 if (fflush(file->f) < 0)
     errnoAbort("Couldn't flush file %s.", file->name);
 }
 
 void _pf_cm_file_flush(_pf_Stack *stack)
 /* Flush file */
 {
 struct file *file = stack[0].v;
 _pf_nil_check(file);
 mustFlush(file);
 }
 
 void _pf_cm_file_writeNow(_pf_Stack *stack)
 /* paraFlow run time support routine to write string to file
  * and then flush. */
 {
 struct file *file = stack[0].v;
 struct _pf_string *string = stack[1].String;
 
 mustWrite(file->f, string->s, string->size);
 mustFlush(file);
 
 /* Clean up references on stack. */
 if (--string->_pf_refCount <= 0)
     string->_pf_cleanup(string, 0);
 }
 
 
 void _pf_cm_file_put(_pf_Stack *stack)
 /* Print to file with line feed. */
 {
 struct file *file = stack[0].v;
 FILE *f = file->f;
 _pf_prin(f, stack+1, TRUE);
 fputc('\n', f);
 }
 
 void _pf_cm_file_get(_pf_Stack *stack)
 /* Read in variable from file, and then make sure have
  * a newline. */
 {
 int c;
 struct file *file = stack[0].v;
 _pf_getObj(file->f, stack);
 c = getc(file->f);
 if (c != '\n')
     warn("expecting newline, got %c", c);
 }
 
 
 void _pf_cm_file_readLine(_pf_Stack *stack)
 /* Read next line from file. */
 {
 struct file *file = stack[0].v;
 FILE *f = file->f;
 struct dyString *dy = file->dy;
 int c;
 
 dyStringClear(dy);
 for (;;)
     {
     c = fgetc(f);
     if (c == EOF)
         break;
     dyStringAppendC(dy, c);
     if (c == '\n')
         break;
     }
 stack[0].String = _pf_string_from_const(dy->string);
 }
 
 void _pf_cm_file_read(_pf_Stack *stack)
 /* Read in a fixed number of bytes to string.
  * This will return a string of length zero at
  * EOF, and a string smaller than what is asked
  * for near EOF. */
 {
 struct file *file = stack[0].v;
 _pf_Int count = stack[1].Int;
 _pf_Int bytesRead;
 struct _pf_string *string = _pf_string_new(needLargeMem(count+1), count);
 bytesRead = fread(string->s, 1, count, file->f);
 if (bytesRead <= 0)
     bytesRead = 0;
 string->size = bytesRead;
 string->s[bytesRead] = 0;
 stack[0].String = string;
 }
 
 void _pf_cm_file_seek(_pf_Stack *stack)
 /* Seek to a position. */
 {
 struct file *file = stack[0].v;
 _pf_Long pos = stack[1].Long;
 _pf_Bit fromEnd = stack[2].Bit;
 int whence = (fromEnd ? SEEK_END : SEEK_SET);
 if (fseek(file->f, pos, whence) < 0)
     errnoAbort("seek error on %s", file->name);
 }
 
 void _pf_cm_file_skip(_pf_Stack *stack)
 /* Seek relative to current position. */
 {
 struct file *file = stack[0].v;
 _pf_Long pos = stack[1].Long;
 if (fseek(file->f, pos, SEEK_CUR) < 0)
     errnoAbort("skip error on %s", file->name);
 }
 
 void _pf_cm_file_tell(_pf_Stack *stack)
 /* Return current file position. */
 {
 struct file *file = stack[0].v;
 stack[0].Long = ftell(file->f);
 }
 
 void pf_fileExists(_pf_Stack *stack)
 /* Returns true if file exists. */
 {
 _pf_String string = stack[0].v;
 _pf_nil_check(string);
 stack[0].Bit = fileExists(string->s);
 /* Clean up references on stack. */
 if (--string->_pf_refCount <= 0)
     string->_pf_cleanup(string, 0);
 }
 
 void pf_fileRemove(_pf_Stack *stack)
 /* Remove file. Punt if there's a problem. */
 {
 int err;
 _pf_String string = stack[0].v;
 
 _pf_nil_check(string);
 err = remove(string->s);
 
 /* Clean up references on stack. */
 if (--string->_pf_refCount <= 0)
     string->_pf_cleanup(string, 0);
 
 if (err < 0)
     errnoAbort("Couldn't remove file %s", string->s);
 }
 
 void pf_fileRename(_pf_Stack *stack)
 /* Rename file. */
 {
 int err;
 _pf_String oldName = stack[0].v;
 _pf_String newName = stack[1].v;
 _pf_nil_check(oldName);
 _pf_nil_check(newName);
 
 err = rename(oldName->s, newName->s);
 
 /* Clean up references on stack. */
 if (--oldName->_pf_refCount <= 0)
     oldName->_pf_cleanup(oldName, 0);
 if (--newName->_pf_refCount <= 0)
     newName->_pf_cleanup(newName, 0);
 
 if (err < 0)
     errnoAbort("Couldn't rename file %s to %s", oldName->s, newName->s);
 }
 
 void pf_httpConnect(_pf_Stack *stack)
 /* Return an open HTTP connection in a file, with
  * most of the header sent.  Doesn't send the
  * last part though, so you can put out cookies. 
  * Implements:
  *   to httpConnect(string url, method, protocol, agent) into (file f) */
 {
 /* Fetch input from stack. */
 _pf_String url = stack[0].String;
 _pf_String method = stack[1].String;
 _pf_String protocol = stack[2].String;
 _pf_String agent = stack[3].String;
 int fd;
 
 /* The usual null checks on input. */
 _pf_nil_check(url);
 _pf_nil_check(method);
 _pf_nil_check(protocol);
 _pf_nil_check(agent);
 
 /* Do the real work of opening network connection and saving
  * result on return stack. */
-fd = netHttpConnect(url->s, method->s, agent->s, protocol->s);
+fd = netHttpConnect(url->s, method->s, agent->s, protocol->s, NULL);
 stack[0].v = fileFromFILE(mustFdopen(fd, url->s, "r+"), url);
 
 /* Clean up input, except for URL which got moved to file. */
 if (--method->_pf_refCount <= 0)
     method->_pf_cleanup(method, 0);
 if (--protocol->_pf_refCount <= 0)
     protocol->_pf_cleanup(protocol, 0);
 if (--agent->_pf_refCount <= 0)
     agent->_pf_cleanup(agent, 0);
 }