942664daefc452c28bb86f3623774ffcebfc5e90
kent
  Wed Oct 27 17:54:38 2010 -0700
Adding new functions udcFileReadAll and udcWrapShortLineFile
diff --git src/lib/udc.c src/lib/udc.c
index 0c36b96..1996b73 100644
--- src/lib/udc.c
+++ src/lib/udc.c
@@ -13,30 +13,31 @@
  * gets mapped to:
  *     rootCacheDir/http/genome.ucsc.edu/cgi-bin/hgGateway/
  * The URL protocol is the first directory under the root, and the remainder of the
  * URL, with some necessary escaping, is used to define the rest of the cache directory
  * structure, with each '/' after the protocol line translating into another directory
  * level.
  *    
  * The bitmap file contains time stamp and size data as well as an array with one bit
  * for each block of the file that has been fetched.  Currently the block size is 8K. */
 
 #include <sys/file.h>
 #include "common.h"
 #include "hash.h"
 #include "obscure.h"
 #include "bits.h"
+#include "linefile.h"
 #include "portable.h"
 #include "sig.h"
 #include "net.h"
 #include "cheapcgi.h"
 #include "udc.h"
 
 static char const rcsid[] = "$Id: udc.c,v 1.37 2010/03/19 19:16:37 angie Exp $";
 
 #define udcBlockSize (8*1024)
 /* All fetch requests are rounded up to block size. */
 
 #define udcMaxBytesPerRemoteFetch (udcBlockSize * 32)
 /* Very large remote reads are broken down into chunks this size. */
 
 struct connInfo
@@ -1301,31 +1302,61 @@
 	memcpy(newBuf, buf, bufSize);
 	freeMem(longBuf);
 	buf = longBuf = newBuf;
 	bufSize = newBufSize;
 	}
     char c = udcGetChar(file);
     buf[i] = c;
     if (c == 0)
         break;
     }
 char *retString = cloneString(buf);
 freeMem(longBuf);
 return retString;
 }
 
+char *udcFileReadAll(char *url, char *cacheDir, size_t maxSize, size_t *retSize)
+/* Read a complete file via UDC. The cacheDir may be null in which case udcDefaultDir()
+ * will be used.  If maxSize is non-zero, check size against maxSize
+ * and abort if it's bigger.  Returns file data (with an extra terminal for the
+ * common case where it's treated as a C string).  If retSize is non-NULL then
+ * returns size of file in *retSize. Do a freeMem or freez of the returned buffer
+ * when done. */
+{
+struct udcFile  *file = udcFileOpen(url, cacheDir);
+size_t size = file->size;
+if (maxSize != 0 && size > maxSize)
+    errAbort("%s is %lld bytes, but maxSize to udcFileReadAll is %lld",
+    	url, (long long)size, (long long)maxSize);
+char *buf = needLargeMem(size+1);
+udcMustRead(file, buf, size);
+buf[size] = 0;	// add trailing zero for string processing
+udcFileClose(&file);
+if (retSize != NULL)
+    *retSize = size;
+return buf;
+}
 
+struct lineFile *udcWrapShortLineFile(char *url, char *cacheDir, size_t maxSize)
+/* Read in entire short (up to maxSize) url into memory and wrap a line file around it.
+ * The cacheDir may be null in which case udcDefaultDir() will be used.  If maxSize
+ * is zero then a default value (currently 64 meg) will be used. */
+{
+if (maxSize == 0) maxSize = 64 * 1024 * 1024;
+char *buf = udcFileReadAll(url, cacheDir, maxSize, NULL);
+return lineFileOnString(url, TRUE, buf);
+}
 
 void udcSeek(struct udcFile *file, bits64 offset)
 /* Seek to a particular position in file. */
 {
 file->offset = offset;
 mustLseek(file->fdSparse, offset, SEEK_SET);
 }
 
 bits64 udcTell(struct udcFile *file)
 /* Return current file position. */
 {
 return file->offset;
 }
 
 static bits64 rCleanup(time_t deleteTime, boolean testOnly)