⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 datasourceweb.c

📁 数据挖掘经典的hierarchial clustering algorithm
💻 C
字号:
/*
  ========================================================================
  DEVise Data Visualization Software
  (c) Copyright 1992-1996
  By the DEVise Development Group
  Madison, Wisconsin
  All Rights Reserved.
  ========================================================================

  Under no circumstances is this software to be copied, distributed,
  or altered in any way without prior permission from the DEVise
  Development Group.
*/

/*
  Implementation of DataSourceWeb class.

  It derives from the DataSourceFileDesc class and makes _file
  be the file pointer of the cache file instead of the fdopen()'d
  pointer to the file descriptor of the socket which is the default
  behavior of the DataSourceFileDesc class.
 */

/*
  $Id: DataSourceWeb.c,v 1.7 1996/10/04 17:10:43 wenger Exp $

  $Log: DataSourceWeb.c,v $
  Revision 1.7  1996/10/04 17:10:43  wenger
  Fixed error in open_ftp() call that prevented compile.

  Revision 1.6  1996/10/02 19:47:15  jussi
  Added support for opening an HTTP connection for writing (posting)
  Web data.

  Revision 1.5  1996/10/02 15:23:48  wenger
  Improved error handling (modified a number of places in the code to use
  the DevError class).

  Revision 1.4  1996/07/14 20:34:09  jussi
  Rewrote class to fork a process that does all data transfers
  from the Web site.

  Revision 1.3  1996/07/12 19:37:21  jussi
  Added timeout processing for network connections.

  Revision 1.2  1996/07/02 22:48:14  jussi
  Fixed small bug in AsyncIO. Close() no longer uses the base
  class Close() routine.

  Revision 1.1  1996/07/01 19:21:24  jussi
  Initial revision.
*/

#define _DataSourceWeb_c_

//#define DEBUG

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/param.h>
#include <sys/types.h>
#include <sys/stat.h>

#include "DataSourceWeb.h"
#include "Timer.h"
#include "Util.h"
#include "Web.h"
#include "DevError.h"

#if !defined(lint) && defined(RCSID)
static char rcsid[] = "$RCSfile: DataSourceWeb.c,v $ $Revision: 1.7 $ $State: Exp $";
#endif

static char * srcFile = __FILE__;

/*------------------------------------------------------------------------------
 * function: DataSourceWeb::DataSourceWeb
 * DataSourceWeb constructor.
 */
DataSourceWeb::DataSourceWeb(char *url, char *label, char *cache) :
        DataSourceFileStream(cache, label)
{
    DO_DEBUG(printf("DataSourceWeb::DataSourceWeb(%s,%s,%s)\n",
                    url, cache, (label != NULL) ? label : "null"));

    _url = strdup(url);
    _childPid = -1;
}

/*------------------------------------------------------------------------------
 * function: DataSourceWeb::~DataSourceWeb
 * DataSourceWeb destructor.
 */
DataSourceWeb::~DataSourceWeb()
{
    DO_DEBUG(printf("DataSourceWeb::~DataSourceWeb()\n"));

    if (_childPid >= 0)
        (void)kill(_childPid, SIGKILL);

    delete _url;
}

/*------------------------------------------------------------------------------
 * function: DataSourceWeb::Open
 * Open Web data source.
 */
DevStatus
DataSourceWeb::Open(char *mode)
{
    DO_DEBUG(printf("DataSourceWeb::Open()\n"));

    DOASSERT(!_file && _childPid < 0, "Invalid file or process id");

    if (strcmp(mode, "r")) {
        reportError("cannot write to a Web data source", EINVAL);
        return StatusFailed;
    }

    // if file can be opened for reading, assume that the cache file
    // is complete and there is no need to fetch more data from the URL
    _file = fopen(_filename, "r");
    if (_file != NULL) {
        return StatusOk;
    }

    // create cache file and close it immediately
    _file = fopen(_filename, "w");
    if (!_file) {
        char    errBuf[MAXPATHLEN+100];
        sprintf(errBuf, "cannot create cache file %s", _filename);
        reportError(errBuf, errno);
        return StatusFailed;
    }
    fclose(_file);

    // reopen cache file for reading
    _file = fopen(_filename, "r");
    DOASSERT(_file, "Inconsistent file activity");

    _childPid = fork();
    if (_childPid < 0) {
        reportError("cannot fork process", errno);
        return StatusFailed;
    }

    if (!_childPid) {
        DevStatus status = ChildProc();
        if (status != StatusOk)
            reportError("Web data transfer failed", errno);
        _exit(1);
    }

    return StatusOk;
}

/*------------------------------------------------------------------------------
 * function: DataSourceWeb::Close
 * Do a close() on the file descriptor.
 */
DevStatus
DataSourceWeb::Close()
{
    DO_DEBUG(printf("DataSourceWeb::Close()\n"));

    if (_childPid >= 0)
        (void)kill(_childPid, SIGKILL);

    _childPid = -1;

    return DataSourceFileStream::Close();
}

/*------------------------------------------------------------------------------
 * function: DataSourceWeb::ChildProc
 * Child process for fetching data from Web source.
 */
DevStatus
DataSourceWeb::ChildProc()
{
    DO_DEBUG(printf("DataSourceWeb::ChildProc()\n"));

    Timer::StopTimer();

    printf("Initiating data transfer from %s\n", _url);

    int fd;
    size_t totlen = 0;

    if (!strncmp(_url, "ftp://", 6))
        fd = open_ftp(_url, 1);
    else
        fd = open_http(_url, 1, &totlen);

    if (fd < 0) {
        fprintf(stderr, "Unable to open URL %s", _url);
        return StatusFailed;
    }

    // attempt to create an empty cache file
    FILE *cfile = fopen(_filename, "w");
    if (!cfile) {
        fprintf(stderr, "Unable to create cache file %s", _filename);
        return StatusFailed;
    }

    char buffer[1024];

    while (1) {
        int len = read(fd, buffer, sizeof buffer);
        if (len == 0) {
            printf("Data transfer from %s complete\n", _url);
            close(fd);
            fclose(cfile);
            return StatusOk;
        }
        if (len < 0) {
            reportErrSys("Cannot read from network");
            break;
        }
        if (fseek(cfile, 0, SEEK_END) < 0) {
            reportErrSys("Cannot seek to end of file");
            break;
        }
        if (fwrite(buffer, len, 1, cfile) != 1) {
            reportErrSys("Cannot write to cache file");
            break;
        }
    }

    close(fd);
    fclose(cfile);

    return StatusFailed;
}

/*------------------------------------------------------------------------------
 * function: DataSourceWeb::Fwrite
 * Do fwrite() on the stream associated with this object.
 */
size_t
DataSourceWeb::Fwrite(const char *buf, size_t size, size_t itemCount)
{
    DO_DEBUG(printf("DataSourceWeb::Fwrite()\n"));

    reportError("writing to Web data source not supported", EINVAL);
    return 0;
}

/*------------------------------------------------------------------------------
 * function: DataSourceWeb::Write
 * Do write() on the stream associated with this object.
 */
size_t
DataSourceWeb::Write(const char *buf, size_t byteCount)
{
    DO_DEBUG(printf("DataSourceWeb::Write()\n"));

    reportError("writing to Web data source not supported", EINVAL);
    return 0;
}

/*------------------------------------------------------------------------------
 * function: DataSourceWeb::append
 * Append the given record to the end of the file associated with this
 * object.
 */
int
DataSourceWeb::append(void *buf, int recSize)
{
    DO_DEBUG(printf("DataSourceWeb::append()\n"));
    int result = 0;

    reportError("writing to Web data source not supported", EINVAL);
    return -1;
}

/*============================================================================*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -