/* qblastapi.c * =========================================================================== * * PUBLIC DOMAIN NOTICE * National Center for Biotechnology Information (NCBI) * * This software/database is a "United States Government Work" under the * terms of the United States Copyright Act. It was written as part of * the author's official duties as a United States Government employee and * thus cannot be copyrighted. This software/database is freely available * to the public for use. The National Library of Medicine and the U.S. * Government do not place any restriction on its use or reproduction. * We would, however, appreciate having the NCBI and the author cited in * any work or product based on this material * * Although all reasonable efforts have been taken to ensure the accuracy * and reliability of the software and data, the NLM and the U.S. * Government do not and cannot warrant the performance or results that * may be obtained by using this software or data. The NLM and the U.S. * Government disclaim all warranties, express or implied, including * warranties of performance, merchantability or fitness for any particular * purpose. * * =========================================================================== * * File Name: qblastapi.c * * Author: Jonathan Kans * * Version Creation Date: 6/28/00 * * $Revision: 1.34 $ * * File Description: * * Modifications: * -------------------------------------------------------------------------- * * $Log: qblastapi.c,v $ * Revision 1.34 2016/10/25 16:53:07 kans * JIRA:SQD-4098 QUERY_OpenUrlQuery sends port 0 instead of 80 * * Revision 1.33 2006/07/13 17:03:51 bollin * resolved compiler warnings * * Revision 1.32 2005/11/28 17:49:55 coulouri * correction to previous commit; define snprintf for windows * * Revision 1.31 2005/11/28 15:32:11 coulouri * do not overflow string buffer if BioseqGetTitle() returns NULL * * Revision 1.30 2004/02/23 15:30:02 lavr * New (last) parameter "how" added in CONN_Write() API call * * Revision 1.29 2004/02/20 17:13:01 madden * Doubled some timeouts * * Revision 1.28 2003/11/14 16:23:08 dondosha * If query id not local, append title to id to get defline in BLASTGetQuerySummary * * Revision 1.27 2003/11/12 21:19:03 kans * changed query_number to query_num - fixing typo * * Revision 1.26 2003/11/12 20:49:20 coulouri * Replace code accidentally removed between 1.24 and 1.25 in BlastGetQueryBioseqByRIDEx * * Revision 1.25 2003/11/03 20:50:53 madden * Fix problem with content length, remove call to QblastTestRID, add BLASTGetBOByRIDEx * * Revision 1.24 2003/01/17 20:40:29 madden * Put QUERY_NUMBER back in URL for fetching Seqannot * * Revision 1.23 2003/01/15 22:04:49 madden * Moved BLASTGetSeqAnnotByRIDEx from internal * * Revision 1.22 2003/01/02 15:06:48 boemker * Wrote BLASTGetQueryBioseqByRIDEx that extends behavior of * BLASTGetQueryBioseqByRID by returning the Bioseq for a particular query * (rather than always returning the Bioseq for the first query. Modified * BLASTGetQueryBioseqByRID to use BLASTGetQueryBioseqByRIDEx. Wrote * BLASTGetQuerySummary to return information about a query. * * Revision 1.21 2002/11/08 22:36:17 kans * in synchronous query, loop on == eIO_Timeout instead of != eIO_Success * * Revision 1.20 2002/08/07 18:45:15 lavr * Change from deprecated to current EIO_ReadMethod enums * * Revision 1.19 2002/07/24 21:09:56 kans * reverted ncbi URL * * Revision 1.18 2002/07/23 16:45:21 kans * changed www.ncbi.nlm.nih.gov to www.ncbi.nih.gov * * Revision 1.17 2002/04/12 14:27:35 madden * Check RID for internal jobs, send to appropriate place * * Revision 1.16 2001/02/25 21:50:41 kans * changes from Uint4 to size_t due to connection type changes * * Revision 1.15 2001/02/21 22:07:34 lavr * Changes for use new CONN interface * * Revision 1.14 2000/12/06 17:53:31 madden * make QBBioseqToFasta non-static, fix UMR * * Revision 1.13 2000/12/04 18:07:31 madden * BLASTGetBOByRID uses Blast.cgi * * Revision 1.12 2000/11/07 21:54:52 shavirin * Added new function BLASTGetQueryBioseqByRID(). * * Revision 1.10 2000/08/30 14:55:08 kans * parentheses around cast of currtime - curr->initialTime in printf * * Revision 1.9 2000/07/19 15:16:12 shavirin * Added new function CharPtr BLASTGetBOByRID(CharPtr RID); * * * ========================================================================== */ #include #include #include #include #include #ifdef OS_MAC #include #endif #ifdef _MSC_VER #define strcasecmp _stricmp #define strdup _strdup #define snprintf _snprintf #endif static CharPtr ReadALine (CharPtr str, size_t size, FILE *fp) { Char ch; CharPtr ptr; CharPtr rsult; if (str == NULL || size < 1 || fp == NULL) return NULL; *str = '\0'; rsult = fgets (str, size, fp); if (rsult != NULL) { ptr = str; ch = *ptr; while (ch != '\0' && ch != '\n' && ch != '\r') { ptr++; ch = *ptr; } *ptr = '\0'; } return rsult; } NLM_EXTERN CONN QBlastOpenConnection ( void ) { return QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/blast/Blast.cgi", NULL, "qblastapp", 30, eMIME_T_Application, eMIME_WwwForm, eENCOD_Url, 0); } NLM_EXTERN EIO_Status QBlastWaitForReply ( CONN conn ) { time_t currtime, starttime; time_t max = 0; EIO_Status status; STimeout timeout; #ifdef OS_MAC EventRecord currEvent; #endif if (conn == NULL) return eIO_Unknown; #ifdef OS_MAC timeout.sec = 0; timeout.usec = 0; #else timeout.sec = 100; timeout.usec = 0; #endif starttime = GetSecs (); while ((status = CONN_Wait (conn, eIO_Read, &timeout)) == eIO_Timeout && max < 300) { currtime = GetSecs (); max = currtime - starttime; #ifdef OS_MAC WaitNextEvent (0, &currEvent, 0, NULL); #endif } return status; } typedef struct QBQueueTag { Char rid [64]; Char seqid [41]; time_t estTime; time_t initialTime; time_t postedTime; Int2 secondsToWait; QBlastResultProc resultproc; QBlastAnnounceProc announceproc; Nlm_VoidPtr userdata; QUEUE connqueue; Boolean ready; Boolean fetching; Boolean done; struct QBQueueTag* next; } QBlastQueue, PNTR QBQueuePtr; static Boolean LIBCALLBACK ThirdQBlastCallback ( CONN conn, Nlm_VoidPtr userdata, EIO_Status status ) { QBQueuePtr cqp; FILE *fp; Char path [PATH_MAX]; cqp = (QBQueuePtr) userdata; TmpNam (path); fp = FileOpen (path, "w"); QUERY_CopyResultsToFile (conn, fp); FileClose (fp); cqp->resultproc (path, cqp->userdata, cqp->rid, cqp->seqid, TRUE); cqp->done = TRUE; FileRemove (path); return TRUE; } static Boolean LIBCALLBACK SecondQBlastCallback ( CONN conn, Nlm_VoidPtr userdata, EIO_Status status ) { QBQueuePtr cqp; FILE *fp; Char line [256]; Char path [PATH_MAX]; CharPtr sttus; CharPtr str; Boolean waiting = FALSE; /* look for waiting, failure, or success */ cqp = (QBQueuePtr) userdata; TmpNam (path); fp = FileOpen (path, "w"); QUERY_CopyResultsToFile (conn, fp); FileClose (fp); fp = FileOpen (path, "r"); str = ReadALine (line, sizeof (line), fp); while (str != NULL) { if (! StringHasNoText (line)) { sttus = StringStr (line, "Status="); if (sttus != NULL) { sttus += 7; if (StringStr (sttus, "WAITING") != NULL) { waiting = TRUE; } else if (StringStr (sttus, "READY") != NULL) { cqp->ready = TRUE; /* } else if (StringStr (sttus, "FAILED") != NULL) { cqp->done = TRUE; */ } } } str = ReadALine (line, sizeof (line), fp); } FileClose (fp); if (cqp->done) { cqp->resultproc (NULL, cqp->userdata, cqp->rid, cqp->seqid, FALSE); } FileRemove (path); return TRUE; } static Boolean LIBCALLBACK FirstQBlastCallback ( CONN conn, Nlm_VoidPtr userdata, EIO_Status status ) { QBQueuePtr cqp; FILE *fp; Char line [256]; Char path [PATH_MAX]; CharPtr ptr; Char rid [64]; time_t rtoe; CharPtr str; long int val; /* read rID or failure message */ cqp = (QBQueuePtr) userdata; TmpNam (path); fp = FileOpen (path, "w"); QUERY_CopyResultsToFile (conn, fp); FileClose (fp); rid [0] = '\0'; rtoe = 15; fp = FileOpen (path, "r"); str = ReadALine (line, sizeof (line), fp); while (str != NULL) { if (! StringHasNoText (line)) { ptr = StringStr (line, "RID = "); if (ptr != NULL) { ptr += 6; StringNCpy_0 (rid, ptr, sizeof (rid)); } ptr = StringStr (line, "RTOE = "); if (ptr != NULL) { ptr += 7; if (sscanf (ptr, "%ld", &val) == 1) { rtoe = (time_t) val; } } } str = ReadALine (line, sizeof (line), fp); } FileClose (fp); FileRemove (path); if (! StringHasNoText (rid)) { StringNCpy_0 (cqp->rid, rid, sizeof (cqp->rid)); cqp->estTime = (time_t) rtoe; cqp->secondsToWait = (Int2) rtoe + 2; if (cqp->secondsToWait > 15) { cqp->secondsToWait = 15; } if (cqp->announceproc != NULL) { cqp->announceproc (rid, cqp->seqid, (Int2) val); } } else { cqp->done = TRUE; if (cqp->resultproc != NULL) { cqp->resultproc (NULL, cqp->userdata, cqp->rid, cqp->seqid, FALSE); } } return TRUE; } static void QBlast_AddToQueue ( QBQUEUE * queue, QBlastResultProc resultproc, QBlastAnnounceProc announceproc, Nlm_VoidPtr userdata, CONN conn, BioseqPtr bsp, CharPtr rid ) { QBQueuePtr cqp; QBQueuePtr PNTR qptr; QBQueuePtr tmp; if (queue == NULL || resultproc == NULL || conn == NULL) return; /* allocate queue element */ cqp = (QBQueuePtr) MemNew (sizeof (QBlastQueue)); if (cqp == NULL) return; cqp->rid [0] = '\0'; if (rid != NULL) { StringNCpy_0 (cqp->rid, rid, sizeof (cqp->rid)); } cqp->seqid [0] = '\0'; if (bsp != NULL) { SeqIdWrite (bsp->id, cqp->seqid, PRINTID_FASTA_LONG, 40); } cqp->estTime = 0; cqp->initialTime = GetSecs (); cqp->postedTime = cqp->initialTime; cqp->secondsToWait = 15; cqp->resultproc = resultproc; cqp->announceproc = announceproc; cqp->userdata = userdata; cqp->connqueue = NULL; cqp->ready = FALSE; cqp->fetching = FALSE; cqp->done = FALSE; /* add to polling queue */ qptr = (QBQueuePtr PNTR) queue; if (qptr != NULL) { if (*qptr != NULL) { tmp = *qptr; if (tmp != NULL) { while (tmp->next != NULL) { tmp = tmp->next; } tmp->next = cqp; } } else { *qptr = cqp; } } /* queue the request for a rID */ if (bsp != NULL) { QUERY_AddToQueue (&(cqp->connqueue), conn, FirstQBlastCallback, (Pointer) cqp, TRUE); } else if (rid != NULL) { QUERY_AddToQueue (&(cqp->connqueue), conn, SecondQBlastCallback, (Pointer) cqp, TRUE); } } /* print just the sequence with no punctuation */ static Boolean QBlastFastaFileFunc (BioseqPtr bsp, Int2 key, CharPtr buf, Uint4 buflen, Pointer data) { FILE * fp; CharPtr bufr; size_t len, bufsize; size_t src_read, dst_written; fp = (FILE *)data; switch (key) { case FASTA_ID: len = StringLen (buf); if (len > 0) { bufsize = len * 3 + 2; bufr = MemNew (bufsize); if (bufr != NULL) { URL_Encode (buf, len, &src_read, bufr, bufsize, &dst_written); fprintf (fp, "%s", "%3E"); fprintf(fp, "%s+", bufr); } MemFree (bufr); } /* fprintf(fp, ">%s ", buf); */ break; case FASTA_DEFLINE: len = StringLen (buf); if (len > 0) { bufsize = len * 3 + 2; bufr = MemNew (bufsize); if (bufr != NULL) { URL_Encode (buf, len, &src_read, bufr, bufsize, &dst_written); fprintf(fp, "%s", bufr); fprintf (fp, "%s", "%0D%0A"); } MemFree (bufr); } /* fprintf(fp, "%s\n", buf); */ break; case FASTA_SEQLINE: fprintf(fp, "%s", buf); /* no newline */ break; case FASTA_EOS: /* end of sequence */ break; default: break; } return TRUE; } #define QB_FASTA_BUFFER_LEN 400 Boolean QBBioseqToFasta (BioseqPtr bsp, FILE *fp, Boolean is_na) { MyFsa mfa; Char buf [QB_FASTA_BUFFER_LEN + 1]; if (bsp == NULL || fp == NULL) return FALSE; MemSet(&mfa, 0, sizeof(MyFsa)); mfa.buf = buf; mfa.buflen = QB_FASTA_BUFFER_LEN; mfa.seqlen = 80; mfa.mydata = (Pointer)fp; mfa.myfunc = QBlastFastaFileFunc; mfa.bad_asn1 = FALSE; mfa.order = 0; mfa.accession = NULL; mfa.organism = NULL; mfa.do_virtual = FALSE; mfa.tech = 0; mfa.no_sequence = FALSE; mfa.formatdb = FALSE; return BioseqToFastaX (bsp, &mfa, is_na); } NLM_EXTERN Boolean QBlastAsynchronousRequest ( CharPtr database, CharPtr program, BioseqPtr bsp, QBQUEUE* queue, QBlastResultProc resultproc, QBlastAnnounceProc announceproc, VoidPtr userdata ) { CONN conn; FILE *fp; size_t n_written; Char path [PATH_MAX]; Char str [256]; if (bsp == NULL || queue == NULL || resultproc == NULL) return FALSE; if (StringHasNoText (database)) { database = "nr"; } if (StringHasNoText (program)) { program = "blastn"; } sprintf (str, "DATABASE=%s&PROGRAM=%s&CMD=Put&QUERY_BELIEVE_DEFLINE=yes&QUERY=", database, program); conn = QBlastOpenConnection (); if (conn == NULL) return FALSE; TmpNam (path); fp = FileOpen (path, "w"); QBBioseqToFasta (bsp, fp, ISA_na (bsp->mol)); FileClose (fp); fp = FileOpen (path, "r"); CONN_Write (conn, (const void *) str, StringLen (str), &n_written, eIO_WritePersist); QUERY_CopyFileToQuery (conn, fp); FileClose (fp); QUERY_SendQuery (conn); QBlast_AddToQueue (queue, resultproc, announceproc, userdata, conn, bsp, NULL); FileRemove (path); return TRUE; } static void QBlast_RemoveFromQueue ( QBQUEUE* queue, QBQueuePtr freeme ) { QBQueuePtr curr; QBQueuePtr next; QBQueuePtr PNTR prev; QBQueuePtr PNTR qptr; qptr = (QBQueuePtr PNTR) queue; if (qptr == NULL || *qptr == NULL || freeme == NULL) return; prev = qptr; curr = *qptr; while (curr != NULL) { next = curr->next; if (curr == freeme) { *(prev) = next; curr->next = NULL; MemFree (curr); } else { prev = &(curr->next); } curr = next; } } NLM_EXTERN Int4 QBlastCheckQueue ( QBQUEUE* queue ) { CONN conn; Nlm_Int4 count = 0; QBQueuePtr curr; time_t currtime; QBQueuePtr next; size_t n_written; QBQueuePtr PNTR qptr; Char str [80]; qptr = (QBQueuePtr PNTR) queue; if (qptr == NULL || *qptr == NULL) return 0; curr = *qptr; /* first loop through actual url requests, call first-third callbacks */ while (curr != NULL) { next = curr->next; /* check for return of rID, WAITING, of SUCCESS message */ QUERY_CheckQueue (&(curr->connqueue)); if (curr->done) { QBlast_RemoveFromQueue (queue, curr); } curr = next; } /* now send new url queries if appropriate */ curr = *qptr; if (curr == NULL) return 0; while (curr != NULL) { next = curr->next; if (curr->done) { QBlast_RemoveFromQueue (queue, curr); } else { if ((! curr->fetching) && (! curr->ready) && curr->connqueue == NULL) { currtime = GetSecs (); if (currtime - curr->postedTime < curr->secondsToWait) { } else if (! StringHasNoText (curr->rid)) { /* estimated wait time has expired, so queue another check */ if (curr->secondsToWait < 60) { curr->secondsToWait *= 2; } curr->postedTime = GetSecs (); sprintf (str, "RID=%s&CMD=Get\n", curr->rid); conn = QBlastOpenConnection (); if (conn != NULL) { CONN_Write (conn, (const void *) str, StringLen (str), &n_written, eIO_WritePersist); QUERY_SendQuery (conn); QUERY_AddToQueue (&(curr->connqueue), conn, SecondQBlastCallback, (Pointer) curr, TRUE); } else { ErrPostEx (SEV_ERROR, 0, 0, "Unable to open QBlast connection"); } } } count++; } if ((! curr->done) && curr->ready && (! curr->fetching) && curr->connqueue == NULL) { curr->fetching = TRUE; sprintf (str, "CMD=Get&RID=%s&FORMAT_OBJECT=Alignment&FORMAT_TYPE=ASN.1\n", curr->rid); conn = QBlastOpenConnection (); if (conn != NULL) { CONN_Write (conn, (const void *) str, StringLen (str), &n_written, eIO_WritePersist); QUERY_SendQuery (conn); QUERY_AddToQueue (&(curr->connqueue), conn, ThirdQBlastCallback, (Pointer) curr, TRUE); } else { ErrPostEx (SEV_ERROR, 0, 0, "Unable to open QBlast connection"); } } curr = next; } return count; } NLM_EXTERN Boolean QBlastCheckRequest ( CharPtr rid, QBQUEUE* queue, QBlastResultProc resultproc, QBlastAnnounceProc announceproc, VoidPtr userdata ) { CONN conn; size_t n_written; Char str [256]; if (StringHasNoText (rid) || queue == NULL || resultproc == NULL) return FALSE; sprintf (str, "RID=%s&CMD=Get\n", rid); conn = QBlastOpenConnection (); if (conn == NULL) return FALSE; CONN_Write (conn, (const void *) str, StringLen (str), &n_written, eIO_WritePersist); QUERY_SendQuery (conn); QBlast_AddToQueue (queue, resultproc, announceproc, userdata, conn, NULL, rid); return TRUE; } NLM_EXTERN void QBlastCloseQueue ( QBQUEUE* queue ) { QBQueuePtr curr; QBQueuePtr next; QBQueuePtr PNTR qptr; qptr = (QBQueuePtr PNTR) queue; if (qptr == NULL || *qptr == NULL) return; curr = *qptr; while (curr != NULL) { next = curr->next; if (curr->connqueue != NULL) { QUERY_CloseQueue (&(curr->connqueue)); } QBlast_RemoveFromQueue (queue, curr); curr = next; } } NLM_EXTERN Int4 PrintQBlastQueue ( QBQUEUE* queue, FILE *fp ) { Nlm_Int4 count = 0; QBQueuePtr curr; time_t currtime; QBQueuePtr next; QBQueuePtr PNTR qptr; qptr = (QBQueuePtr PNTR) queue; if (qptr == NULL || *qptr == NULL || fp == NULL) return 0; currtime = GetSecs (); curr = *qptr; while (curr != NULL) { next = curr->next; if (! curr->done) { fprintf (fp, "%s\t%s\t%d\t%d\n", curr->rid, curr->seqid, (int) (currtime - curr->initialTime), (int) curr->estTime); count++; } curr = next; } return count; } static void LIBCALLBACK AsnIoErrorFunc(Int2 type, CharPtr message) { return; } /* Function to get SeqAnnot for RID. We suupose, that search already finished and results are exists on the Qblast repository */ NLM_EXTERN SeqAnnotPtr BLASTGetSeqAnnotByRID(CharPtr RID) { return BLASTGetSeqAnnotByRIDEx(RID, NULL, 0, NULL, 0); } /* Returns a SeqAnnot for a given RID. If host_machine and host_path are set to NULL and host_port to zero Default servers will be used. if query_number is set to zero all will be returned, otherwise the one-based offset query will be returned. */ NLM_EXTERN SeqAnnotPtr BLASTGetSeqAnnotByRIDEx(CharPtr RID, Nlm_CharPtr host_machine, Nlm_Uint2 host_port, Nlm_CharPtr host_path, Int4 query_number) { Char query_string[256]; CONN conn; SeqAnnotPtr annot; size_t n_written; Int4 length; AsnIoConnPtr aicp; EIO_Status status; sprintf(query_string, "FORMAT_TYPE=ASN.1&CMD=Get&RID=%s&QUERY_NUMBER=%ld&FORMAT_OBJECT=Alignment", RID, (long) query_number); conn = QUERY_OpenUrlQuery ((host_machine == NULL) ? "www.ncbi.nlm.nih.gov" : host_machine, (host_port <= 0) ? 0 : host_port, (host_path == NULL) ? "/blast/Blast.cgi" : host_path, NULL, "BLASTGetSeqAnnotByRIDEx()", 240, eMIME_T_Application, eMIME_WwwForm, eENCOD_Url, 0); length = StringLen(query_string); status = CONN_Write (conn, query_string, length, &n_written, eIO_WritePersist); QUERY_SendQuery (conn); aicp = QUERY_AsnIoConnOpen ("r", conn); AsnIoSetErrorMsg(aicp->aip, AsnIoErrorFunc); annot = SeqAnnotAsnRead (aicp->aip, NULL); QUERY_AsnIoConnClose (aicp); CONN_Close(conn); return annot; } /* Function to get Bioseq for RID. We suupose, that search already finished and results are exists on the Qblast repository */ NLM_EXTERN BioseqPtr BLASTGetQueryBioseqByRID(CharPtr RID) { return BLASTGetQueryBioseqByRIDEx(RID, 0); } NLM_EXTERN BioseqPtr BLASTGetQueryBioseqByRIDEx(CharPtr RID, int query_num) { Char query_string[256]; CONN conn; BioseqPtr bsp; size_t n_written; Int4 length; AsnIoConnPtr aicp; EIO_Status status; sprintf(query_string, "FORMAT_TYPE=ASN.1&CMD=Get&RID=%s&QUERY_NUMBER=%ld&FORMAT_OBJECT=Bioseq", RID, (long) query_num); conn = QUERY_OpenUrlQuery ("www.ncbi.nlm.nih.gov", 0, "/blast/Blast.cgi", NULL, "BLASTGetQueryBioseqByRIDEx()", 60, eMIME_T_Application, eMIME_WwwForm, eENCOD_Url, 0); length = StringLen(query_string); status = CONN_Write (conn, query_string, length, &n_written, eIO_WritePersist); QUERY_SendQuery (conn); aicp = QUERY_AsnIoConnOpen ("r", conn); AsnIoSetErrorMsg(aicp->aip, AsnIoErrorFunc); bsp = BioseqAsnRead (aicp->aip, NULL); QUERY_AsnIoConnClose (aicp); CONN_Close(conn); return bsp; } NLM_EXTERN Nlm_Boolean BLASTGetQuerySummary(CharPtr RID, Int4 query_number, CharPtr *defline, Int4Ptr query_length) { BioseqPtr bsp = BLASTGetQueryBioseqByRIDEx(RID, query_number); if(!bsp) return FALSE; if (bsp->id->choice == SEQID_LOCAL) { *defline = StringSave(BioseqGetTitle(bsp)); } else { #define SEQID_LENGTH 255 Int4 id_length; Char tmp[SEQID_LENGTH+1]; Int4 title_length = StringLen(BioseqGetTitle(bsp)); SeqIdWrite(bsp->id, tmp, PRINTID_FASTA_LONG, SEQID_LENGTH); id_length = StringLen(tmp); title_length += id_length + 3; *defline = (CharPtr) MemNew(title_length*sizeof(Char)); snprintf(*defline, title_length, "%s %s", tmp, BioseqGetTitle(bsp)); } *query_length = BioseqGetLen(bsp); BioseqFree(bsp); return TRUE; } /* Function to get BlastObject for RID. We suupose, that search already finished and results are exists on the Qblast repository. Blast Object ASN.1 will be returned as CharPtr buffer*/ /* * retrive blast object */ NLM_EXTERN CharPtr BLASTGetBOByRIDEx(CharPtr RID, Nlm_CharPtr host_machine, Nlm_Uint2 host_port, Nlm_CharPtr host_path) { Char query_string[256]; CONN conn; size_t n_written; size_t bytes; Int4 length, buff_len, new_size; EIO_Status status; CharPtr in_buff; sprintf(query_string, "CMD=Get&RID=%s&FORMAT_OBJECT=BlastObject&FORMAT_TYPE=ASN.1", RID); conn = QUERY_OpenUrlQuery ((host_machine == NULL) ? "www.ncbi.nlm.nih.gov" : host_machine, (host_port <= 0) ? 0 : host_port, (host_path == NULL) ? "/blast/Blast.cgi" : host_path, NULL, "BLASTGetBOByRIDEx()", 60, eMIME_T_Application, eMIME_WwwForm, eENCOD_Url, 0); length = StringLen(query_string); status = CONN_Write (conn, query_string, length, &n_written, eIO_WritePersist); QUERY_SendQuery (conn); new_size = 1024; if((in_buff = (CharPtr)MemNew(new_size)) == NULL) { ErrPostEx(SEV_ERROR, 0, 0, "Error in allocating memory\n"); return NULL; } buff_len = 0; while ((status = CONN_Read(conn, in_buff + buff_len, 1024, &bytes, eIO_ReadPlain)) == eIO_Success) { if(bytes == 0) break; new_size += bytes; buff_len += bytes; if ((in_buff = (CharPtr)Realloc(in_buff, new_size)) == NULL) { ErrPostEx(SEV_ERROR, 0, 0, "Error in reallocating memory\n"); return NULL; } } in_buff[buff_len] = NULLB; CONN_Close(conn); return in_buff; } NLM_EXTERN CharPtr BLASTGetBOByRID(CharPtr RID) { return BLASTGetBOByRIDEx(RID, NULL, 0, NULL); }