/*
* 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;
}
}
};
}
|