SOL9 2.0 Class: UrlCacheEntryStream

 SOL9 C++ Class Library  SOL9 Samples  SOL9 Tutorial  SOL9 FAQ  SOL9 ClassTree 

Source code

/*
 * UrlCacheEntryStream.h 
 * Copyright (c) 2011 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */


// SOL9
// 2012/01/20

#pragma once

#include <sol/Object.h>
#include <sol/NullPointerException.h>
#include <sol/HTMLEncoder.h>
#include <sol/StringBufferT.h>
#include <sol/ArgListT.h>
#include <sol/Bytes.h>
#include <sol/FileNotFoundException.h>
#include <wininet.h>
#include <sol/URLDecoder.h>
#include <sol/Bytes.h>
#include <sol/Writer.h>
#include <sol/File.h>
#include <sol/wininet/UrlCacheEntry.h>
#pragma    comment(lib,"wininet.lib")

namespace SOL {


class UrlCacheEntryStream :public UrlCacheEntry{

private:
    HANDLE hStream;
    DWORD  streamSize;

public:
    UrlCacheEntryStream(const TCHAR* urlName)
    :UrlCacheEntry(urlName),
    hStream(NULL), streamSize(0)
    {
        if (urlName) {
            open(urlName);
        }
    }

private:
    bool open(const TCHAR* urlName)
    {
        bool rc = false;

        DWORD size = 0;

        hStream = RetrieveUrlCacheEntryStream(urlName, NULL, &size, FALSE, 0);

        DWORD err = GetLastError();
        if (err == ERROR_FILE_NOT_FOUND) {
            throw Exception(0, _T("RetrieveUrlCacheEntryStream FileNotFound:%s"), urlName);
        }
        if (err == ERROR_INSUFFICIENT_BUFFER) {
            
            INTERNET_CACHE_ENTRY_INFO* cacheEntryInfo = (INTERNET_CACHE_ENTRY_INFO*)new BYTE[size];
            if (cacheEntryInfo) {        
                hStream = RetrieveUrlCacheEntryStream(urlName, cacheEntryInfo, &size, FALSE, 0);
                streamSize  = cacheEntryInfo->dwSizeLow;
                delete [] cacheEntryInfo;

                if (hStream== NULL) {
                    throw Exception("Failed to call RetrieveUrlCacheEntryStream");
                }
                rc = true;
            }
        }
        return rc;
    }

public:
    bool read(__out Bytes& bytes)
    { 
        bool rc = false;

        if (streamSize >0) {
        
            BYTE* buffer = new BYTE[streamSize];
            if (ReadUrlCacheEntryStream(hStream, 0, (void*)buffer, &streamSize, 0)) {
                bytes.shallowCopy(buffer, streamSize);
                rc = true;
            } else {
                delete [] buffer;
            }
        }
        return rc;
    }


public:
    DWORD read(DWORD position, BYTE* buffer, DWORD& bsize)
    { 
        DWORD rc = 0;

        if (streamSize >0) {
            if (position >=0 && position < streamSize && bsize >0) {
                if (ReadUrlCacheEntryStream(hStream, position, (void*)buffer, &bsize, 0)) {
                    rc = bsize;
                }
            }
        }
        return rc;
    }

public:
    bool copy(const TCHAR* dest) 
    {
        bool rc = false;
        if (dest == NULL) {
            return rc;
        }

        if (hStream) {
            File file;
            if (file.create(dest)) {
                const DWORD bsize = 1024;

                BYTE buffer[bsize];
                size_t rest = streamSize;
                DWORD position = 0;
                DWORD size = 0;
                while (rest>0) {
                    size = bsize;
                    if (rest < bsize) {
                        size = rest;
                    }
                    int rsize = read(position, buffer, size);
                    position += rsize;
                    file.write(buffer, rsize);
                    rest -= rsize;
                }
                file.close();
                rc = true;
            }
        }
        return rc;
    }

public:
    ~UrlCacheEntryStream()
    {
        close();
    }

public:
    void close()
    {
        if (hStream) {
            UnlockUrlCacheEntryStream(hStream, 0);
            hStream = NULL;
            streamSize = 0;
        }
    }


};

}

Last modified: 1 Feb 2012

Copyright (c) 2009-2012 Antillia.com ALL RIGHTS RESERVED.