code_app/modules/sane_user/HGSaneImpl.cpp

337 lines
6.7 KiB
C++

#include "HGSaneImpl.hpp"
#include "../base/HGInc.h"
HGSaneManagerImpl::HGSaneManagerImpl()
{
m_dll = NULL;
m_f_sane_init = NULL;
m_f_sane_exit = NULL;
m_f_sane_get_devices = NULL;
m_f_sane_open = NULL;
m_f_sane_close = NULL;
m_f_sane_start = NULL;
m_f_sane_read = NULL;
m_f_sane_cancel = NULL;
m_f_sane_set_io_mode = NULL;
m_f_sane_strstatus = NULL;
}
HGSaneManagerImpl::~HGSaneManagerImpl()
{
}
HGResult HGSaneManagerImpl::Create(const HGChar* sanePath)
{
if (NULL != m_dll)
{
return HGBASE_ERR_FAIL;
}
HGResult ret = HGBase_CreateDll(sanePath, &m_dll);
if (HGBASE_ERR_OK != ret)
{
return ret;
}
ret = FindFunctions();
if (HGBASE_ERR_OK != ret)
{
HGBase_DestroyDll(m_dll);
m_dll = NULL;
return ret;
}
if (SANE_STATUS_GOOD != m_f_sane_init(NULL, NULL))
{
HGBase_DestroyDll(m_dll);
m_dll = NULL;
return HGBASE_ERR_FAIL;
}
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::Destroy()
{
if (!m_devList.empty())
{
return HGBASE_ERR_FAIL;
}
if (NULL != m_dll)
{
m_f_sane_exit();
HGBase_DestroyDll(m_dll);
m_dll = NULL;
}
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::GetDeviceCount(HGUInt* count)
{
if (NULL == count)
{
return HGBASE_ERR_INVALIDARG;
}
const SANE_Device **device_list;
if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE))
{
return HGBASE_ERR_FAIL;
}
*count = 0;
const SANE_Device** p;
for (p = device_list; *p != NULL; ++p)
++(*count);
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::GetDeviceName(HGUInt index, HGChar* name, HGUInt maxLen)
{
if (NULL == name || 0 == maxLen)
{
return HGBASE_ERR_INVALIDARG;
}
const SANE_Device** device_list;
if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE))
{
return HGBASE_ERR_FAIL;
}
HGUInt count = 0;
const SANE_Device** p;
for (p = device_list; *p != NULL; ++p)
++count;
if (index >= count)
return HGBASE_ERR_INVALIDARG;
if (NULL == device_list[index]->name)
return HGBASE_ERR_FAIL;
if (maxLen < strlen(device_list[index]->name) + 1)
return HGBASE_ERR_FAIL;
strcpy(name, device_list[index]->name);
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::OpenDevice(HGUInt index, HGSaneDeviceImpl** device)
{
if (NULL == device)
{
return HGBASE_ERR_INVALIDARG;
}
const SANE_Device** device_list;
if (SANE_STATUS_GOOD != m_f_sane_get_devices(&device_list, SANE_TRUE))
{
return HGBASE_ERR_FAIL;
}
HGUInt count = 0;
const SANE_Device** p;
for (p = device_list; *p != NULL; ++p)
++count;
if (index >= count)
return HGBASE_ERR_INVALIDARG;
SANE_Handle handle = NULL;
if (SANE_STATUS_GOOD != m_f_sane_open(device_list[index]->name, &handle))
{
return HGBASE_ERR_FAIL;
}
m_f_sane_set_io_mode(handle, SANE_FALSE);
HGSaneDeviceImpl* saneDeviceImpl = new HGSaneDeviceImpl(this);
saneDeviceImpl->devHandle = handle;
m_devList.push_back(saneDeviceImpl);
*device = saneDeviceImpl;
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::CloseDevice(HGSaneDeviceImpl* device)
{
if (NULL == device)
{
return HGBASE_ERR_INVALIDARG;
}
HGResult ret = HGBASE_ERR_FAIL;
std::list<HGSaneDeviceImpl*>::iterator iter;
for (iter = m_devList.begin(); iter != m_devList.end(); ++iter)
{
if (device == *iter)
{
StopDevice(device);
m_f_sane_close(device->devHandle);
delete device;
m_devList.erase(iter);
ret = HGBASE_ERR_OK;
break;
}
}
return ret;
}
HGResult HGSaneManagerImpl::StartDevice(HGSaneDeviceImpl* device, HGSane_DeviceEventCallback func, HGPointer param)
{
if (NULL == device || NULL == func)
{
return HGBASE_ERR_INVALIDARG;
}
if (NULL != device->thread)
{
return HGBASE_ERR_FAIL;
}
if (SANE_STATUS_GOOD != m_f_sane_start(device->devHandle))
{
return HGBASE_ERR_FAIL;
}
device->func = func;
device->param = param;
device->stopThread = HGFALSE;
HGBase_OpenThread(ThreadFunc, device, &device->thread);
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::StopDevice(HGSaneDeviceImpl* device)
{
if (NULL == device)
{
return HGBASE_ERR_INVALIDARG;
}
device->stopThread = HGTRUE;
// 该函数应该打断m_f_sane_read
m_f_sane_cancel(device->devHandle);
HGBase_CloseThread(device->thread);
device->thread = NULL;
device->func = NULL;
device->param = NULL;
device->recvData.clear();
device->imgReady = HGFALSE;
return HGBASE_ERR_OK;
}
HGResult HGSaneManagerImpl::GetImage(HGSaneDeviceImpl* device, HGUInt type, HGUInt origin, HGImage* image)
{
if (NULL == device)
{
return HGBASE_ERR_INVALIDARG;
}
HGBase_EnterLock(device->lock);
HGBool imgReady = device->imgReady;
HGBase_LeaveLock(device->lock);
if (!imgReady)
{
return HGBASE_ERR_FAIL;
}
// 从m_recvData中加载
return HGBASE_ERR_FAIL;
}
void HGSaneManagerImpl::ThreadFunc(HGThread thread, HGPointer param)
{
HGSaneDeviceImpl* p = (HGSaneDeviceImpl*)param;
while (!p->stopThread)
{
SANE_Byte data[2048];
SANE_Int len = 0;
SANE_Status stat = p->mgrImpl->m_f_sane_read(p->devHandle, data, 5000, &len);
if (SANE_STATUS_GOOD == stat)
{
HGBase_EnterLock(p->lock);
for (SANE_Int i = 0; i < len; ++i)
{
p->recvData.push_back(data[i]);
}
HGBase_LeaveLock(p->lock);
}
else
{
assert(NULL != p->func);
if (SANE_STATUS_EOF == stat)
{
HGBase_EnterLock(p->lock);
p->imgReady = HGTRUE;
HGBase_LeaveLock(p->lock);
p->func((HGSaneDevice)p, HGSANE_DEVEVENT_IMGREADY, p->param);
}
else
{
p->func((HGSaneDevice)p, HGSANE_DEVEVENT_ERROR, p->param);
}
break;
}
}
}
HGResult HGSaneManagerImpl::FindFunctions()
{
HGResult ret = HGBASE_ERR_OK;
do
{
ret = HGBase_GetDllProcAddress(m_dll, "sane_init", (HGPointer*)&m_f_sane_init);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_exit", (HGPointer*)&m_f_sane_exit);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_get_devices", (HGPointer*)&m_f_sane_get_devices);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_open", (HGPointer*)&m_f_sane_open);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_close", (HGPointer*)&m_f_sane_close);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_start", (HGPointer*)&m_f_sane_start);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_read", (HGPointer*)&m_f_sane_read);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_cancel", (HGPointer*)&m_f_sane_cancel);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_set_io_mode", (HGPointer*)&m_f_sane_set_io_mode);
if (HGBASE_ERR_OK != ret)
break;
ret = HGBase_GetDllProcAddress(m_dll, "sane_strstatus", (HGPointer*)&m_f_sane_strstatus);
if (HGBASE_ERR_OK != ret)
break;
} while (0);
return ret;
}