/
kovalev
/
1C8-native_API_extention_experiment
Обзор
Документация
Войти
/
kovalev
/
1C8-native_API_extention_experiment
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
AddInNative.cpp
593 строки
17 KB
Yury Kovalev
Добавьте файлы проекта.
14 июн 2024, 18:48
14 июн 2024, 18:48
734fd9b
Код
Авторство
О чём код?
#include "stdafx.h" #if defined(__linux__) || defined(__APPLE__) #include <unistd.h> #include <stdlib.h> #include <signal.h> #include <errno.h> #include <iconv.h> #endif #include <wchar.h> #include "AddInNative.h" #include <string> #include <vector> //#include <iostream> //#include <fstream> //#include <regex> //static wchar_t* g_PropNames[]{ L"size", L"speed" }; //static wchar_t* g_PropNamesRu[]{ L"размер", L"скорость" }; //static wchar_t* g_MethodNames[]{ L"findString", L"FindRegex" }; //static wchar_t* g_MethodNamesRu[]{ L"найтиСтроку", L"найтиСРегулярнымВыражением" }; static std::vector<wchar_t*> g_PropNames{ L"Name", L"Version" }; static std::vector<wchar_t*> g_PropNamesRu{ L"Имя", L"Версия" }; static std::vector<wchar_t*> g_MethodNames{ L"ItsAlive", L"GetVersion", L"GetName" }; static std::vector<wchar_t*> g_MethodNamesRu{ L"ОноЖивое", L"ПолучитьВерсию", L"ПолучитьИмя" }; // TODO: Насколько нужна эта константа? // Почему сразу не инициировать литералом переменную "s_names" static const WCHAR_T g_kClassNames[] = u"YuraClass"; //|OtherClass1|OtherClass2"; long findName(const std::vector<wchar_t*>&, wchar_t**); uint32_t convToShortWchar(WCHAR_T** Dest, const wchar_t* Source, size_t len = 0); uint32_t convFromShortWchar(wchar_t** Dest, const WCHAR_T* Source, uint32_t len = 0); uint32_t getLenShortWcharStr(const WCHAR_T* Source); static AppCapabilities g_capabilities = eAppCapabilitiesInvalid; static std::u16string s_names(g_kClassNames); //---------------------------------------------------------------------------// long GetClassObject(const WCHAR_T* wsName, IComponentBase** pInterface) { if(!*pInterface) { *pInterface= new YuraClass(); return (long)*pInterface; } return 0; } //---------------------------------------------------------------------------// AppCapabilities SetPlatformCapabilities(const AppCapabilities capabilities) { g_capabilities = capabilities; return eAppCapabilitiesLast; } //---------------------------------------------------------------------------// AttachType GetAttachType() { return eCanAttachAny; } //---------------------------------------------------------------------------// long DestroyObject(IComponentBase** pIntf) { if(!*pIntf) return -1; delete *pIntf; *pIntf = 0; return 0; } //---------------------------------------------------------------------------// const WCHAR_T* GetClassNames() { return s_names.c_str(); } //---------------------------------------------------------------------------// //CAddInNative YuraClass::YuraClass() { m_iMemory = nullptr; name = std::wstring(L"KYB test native 1c component"); version = std::wstring(L"0.1.1"); } //---------------------------------------------------------------------------// YuraClass::~YuraClass() { } //---------------------------------------------------------------------------// bool YuraClass::Init(void* pConnection) { return true; } //---------------------------------------------------------------------------// long YuraClass::GetInfo() { return 2000; } //---------------------------------------------------------------------------// void YuraClass::Done() { } ///////////////////////////////////////////////////////////////////////////// // ILanguageExtenderBase //---------------------------------------------------------------------------// bool YuraClass::RegisterExtensionAs(WCHAR_T** wsExtensionName) { if (m_iMemory) { bool allocRes = m_iMemory->AllocMemory( (void**)wsExtensionName, static_cast<unsigned>(extensionName.size() * sizeof(WCHAR_T))); if (allocRes) { convToShortWchar(wsExtensionName, extensionName.data(), extensionName.size()); //**wsExtensionName = *ere; return true; } } return false; } //---------------------------------------------------------------------------// long YuraClass::GetNProps() { return static_cast<long>(std::size(g_PropNames)); } //---------------------------------------------------------------------------// long YuraClass::FindProp(const WCHAR_T* wsPropName) { long plPropNum = -1; wchar_t* propName = nullptr; ::convFromShortWchar(&propName, wsPropName); plPropNum = ::findName(g_PropNames, &propName); if (plPropNum == -1) plPropNum = ::findName(g_PropNamesRu, &propName); return plPropNum; } //---------------------------------------------------------------------------// const WCHAR_T* YuraClass::GetPropName(long lPropNum, long lPropAlias) { WCHAR_T* wsPropName = nullptr; if (lPropNum > g_PropNames.size() - 1) return wsPropName; std::wstring wsCurrentName; switch (static_cast<LocaleVariant>(lPropAlias)) { case LocaleVariant::Eng: wsCurrentName = g_PropNames.at(lPropNum); break; case LocaleVariant::Rus: wsCurrentName = g_PropNamesRu.at(lPropNum); break; default: return wsPropName; } if (m_iMemory) { bool resAllocMemory = m_iMemory->AllocMemory( (void**)&wsPropName, static_cast<unsigned>(wsCurrentName.size() * sizeof(WCHAR_T))); if (!resAllocMemory) { convToShortWchar(&wsPropName, wsCurrentName.data()); } } return wsPropName; } //---------------------------------------------------------------------------// bool YuraClass::GetPropVal(const long lPropNum, tVariant* pvarPropVal) { if (lPropNum > g_PropNames.size() - 1) { pvarPropVal->vt = VTYPE_EMPTY; return false; } Props prop = static_cast<Props>(lPropNum); switch (prop) { case Props::Version: if (m_iMemory) { unsigned stringSize = static_cast<unsigned>(version.size()) + 1; if (m_iMemory->AllocMemory((void**)&(pvarPropVal->pwstrVal), stringSize * sizeof(WCHAR_T))) { pvarPropVal->vt = VTYPE_PWSTR; memcpy(pvarPropVal->pwstrVal, version.data(), version.size() * sizeof(WCHAR_T)); pvarPropVal->wstrLen = version.size(); return true; } } else { pvarPropVal->vt = VTYPE_EMPTY; return false; } break; case Props::Name: if (m_iMemory) { unsigned stringSize = static_cast<unsigned>(name.size()) + 1; if (m_iMemory->AllocMemory((void**)&(pvarPropVal->pwstrVal), stringSize * sizeof(WCHAR_T))) { pvarPropVal->vt = VTYPE_PWSTR; memcpy(pvarPropVal->pwstrVal, name.data(), name.size() * sizeof(WCHAR_T)); pvarPropVal->wstrLen = name.size(); return true; } } else { pvarPropVal->vt = VTYPE_EMPTY; return false; } break; default: pvarPropVal->vt = VTYPE_EMPTY; return false; } } //---------------------------------------------------------------------------// bool YuraClass::SetPropVal(const long lPropNum, tVariant *varPropVal) { if (lPropNum > g_PropNames.size() - 1) { varPropVal->vt = VTYPE_EMPTY; return false; } wchar_t* vol = NULL; Props prop = static_cast<Props>(lPropNum); switch (prop) { case Props::Version: convFromShortWchar(&vol, varPropVal->pwstrVal); version = std::wstring(vol); break; case Props::Name: convFromShortWchar(&vol, varPropVal->pwstrVal); name = std::wstring(vol); break; default: return false; } return true; } //---------------------------------------------------------------------------// bool YuraClass::IsPropReadable(const long lPropNum) { Props props = static_cast<Props>(lPropNum); switch (props) { case Props::Name: return true; break; case Props::Version: return true; break; default: return false; break; } } //---------------------------------------------------------------------------// bool YuraClass::IsPropWritable(const long lPropNum) { bool result{false}; Props props = static_cast<Props>(lPropNum); switch (props) { case Props::Name: result = true; break; case Props::Version: result = true; break; default: result = false; break; } return result; } //---------------------------------------------------------------------------// long YuraClass::GetNMethods() { //return static_cast<long>(Methods::eLastMethod); return static_cast<long>(g_MethodNames.size()); } //---------------------------------------------------------------------------// long YuraClass::FindMethod(const WCHAR_T* wsMethodName) { long metodIndex = -1; wchar_t* metodName = nullptr; ::convFromShortWchar(&metodName, wsMethodName); metodIndex = ::findName(g_MethodNames, &metodName); if (metodIndex == -1) { metodIndex = ::findName(g_MethodNamesRu, &metodName); } return metodIndex; } //---------------------------------------------------------------------------// const WCHAR_T* YuraClass::GetMethodName(const long lMethodNum, const long lMethodAlias) { std::wstring methodName; WCHAR_T* wcMethodName = nullptr; switch (static_cast<LocaleVariant>(lMethodAlias)) { case LocaleVariant::Eng: methodName = g_MethodNames.at(lMethodNum); break; case LocaleVariant::Rus: methodName = g_MethodNamesRu.at(lMethodNum); break; default: return nullptr; } if (m_iMemory) { bool resAllocMemory = m_iMemory->AllocMemory( (void**)&wcMethodName, static_cast<unsigned>(methodName.size() * sizeof(WCHAR_T))); if (!resAllocMemory) { convToShortWchar(&wcMethodName, methodName.data()); } } return wcMethodName; } //---------------------------------------------------------------------------// long YuraClass::GetNParams(const long lMethodNum) { long paramNum{}; auto method = static_cast<Methods>(lMethodNum); switch (method) { case Methods::ItsAlive: paramNum = 0; break; case Methods::GetName: paramNum = 0; break; case Methods::GetVersion: paramNum = 0; break; default: break; } return paramNum; } //---------------------------------------------------------------------------// bool YuraClass::GetParamDefValue(const long lMethodNum, const long lParamNum, tVariant *pvarParamDefValue) { return false; } //---------------------------------------------------------------------------// bool YuraClass::HasRetVal(const long lMethodNum) { bool returnVol = false; auto method = static_cast<Methods>(lMethodNum); switch (method) { case Methods::ItsAlive: returnVol = true; break; case Methods::GetName: returnVol = true; break; case Methods::GetVersion: returnVol = true; break; default: break; } return returnVol; } //---------------------------------------------------------------------------// bool YuraClass::CallAsProc(const long lMethodNum, tVariant* paParams, const long lSizeArray) { return true; } //---------------------------------------------------------------------------// bool YuraClass::CallAsFunc(const long lMethodNum, tVariant* pvarRetValue, tVariant* paParams, const long lSizeArray) { switch (static_cast<Methods>(lMethodNum)) { case Methods::ItsAlive: pvarRetValue->vt = VTYPE_BOOL; pvarRetValue->bVal = true; break; case Methods::GetName: if (m_iMemory) { unsigned stringSize = static_cast<unsigned>(name.size()) + 1; if (m_iMemory->AllocMemory((void**)&(pvarRetValue->pwstrVal), stringSize * sizeof(WCHAR_T))) { pvarRetValue->vt = VTYPE_PWSTR; memcpy(pvarRetValue->pwstrVal, name.data(), name.size() * sizeof(WCHAR_T)); pvarRetValue->wstrLen = name.size(); return true; } else { return false; } } else { pvarRetValue->vt = VTYPE_EMPTY; return false; } break; case Methods::GetVersion: if (m_iMemory) { unsigned stringSize = static_cast<unsigned>(version.size()) + 1; if (m_iMemory->AllocMemory((void**)&(pvarRetValue->pwstrVal), stringSize * sizeof(WCHAR_T))) { pvarRetValue->vt = VTYPE_PWSTR; memcpy(pvarRetValue->pwstrVal, version.data(), version.size() * sizeof(WCHAR_T)); pvarRetValue->wstrLen = version.size(); return true; } else { return false; } } else { pvarRetValue->vt = VTYPE_EMPTY; return false; } break; default: return false; break; } } //---------------------------------------------------------------------------// void YuraClass::SetLocale(const WCHAR_T* loc) { } //---------------------------------------------------------------------------// void ADDIN_API YuraClass::SetUserInterfaceLanguageCode(const WCHAR_T * lang) { } //---------------------------------------------------------------------------// bool YuraClass::setMemManager(void* mem) { m_iMemory = (IMemoryManager*)mem; return m_iMemory != 0; } //---------------------------------------------------------------------------// uint32_t convToShortWchar(WCHAR_T** Dest, const wchar_t* Source, size_t len) { if (!len) len = ::wcslen(Source) + 1; if (!*Dest) *Dest = new WCHAR_T[len]; WCHAR_T* tmpShort = *Dest; wchar_t* tmpWChar = (wchar_t*) Source; uint32_t res = 0; ::memset(*Dest, 0, len * sizeof(WCHAR_T)); #if defined( __linux__ ) || defined(__APPLE__) size_t succeed = (size_t)-1; size_t f = len * sizeof(wchar_t), t = len * sizeof(WCHAR_T); const char* fromCode = sizeof(wchar_t) == 2 ? "UTF-16" : "UTF-32"; iconv_t cd = iconv_open("UTF-16LE", fromCode); if (cd != (iconv_t)-1) { succeed = iconv(cd, (char**)&tmpWChar, &f, (char**)&tmpShort, &t); iconv_close(cd); if(succeed != (size_t)-1) return (uint32_t)succeed; } #endif for (; len; --len, ++res, ++tmpWChar, ++tmpShort) { *tmpShort = (WCHAR_T)*tmpWChar; } return res; } //---------------------------------------------------------------------------// long findName( const std::vector<wchar_t*>& names, wchar_t** name) { long ret = -1; for (int i = 0; i < names.size(); i++) { // if (*(names[i]) == **name) if (!wcscmp(names[i], *name)) { ret = i; break; } } return ret; } //---------------------------------------------------------------------------// uint32_t convFromShortWchar(wchar_t** Dest, const WCHAR_T* Source, uint32_t len) { if (!len) len = getLenShortWcharStr(Source) + 1; if (!*Dest) *Dest = new wchar_t[len]; wchar_t* tmpWChar = *Dest; WCHAR_T* tmpShort = (WCHAR_T*)Source; uint32_t res = 0; ::memset(*Dest, 0, len * sizeof(wchar_t)); #if defined( __linux__ ) || defined(__APPLE__) size_t succeed = (size_t)-1; const char* fromCode = sizeof(wchar_t) == 2 ? "UTF-16" : "UTF-32"; size_t f = len * sizeof(WCHAR_T), t = len * sizeof(wchar_t); iconv_t cd = iconv_open("UTF-32LE", fromCode); if (cd != (iconv_t)-1) { succeed = iconv(cd, (char**)&tmpShort, &f, (char**)&tmpWChar, &t); iconv_close(cd); if(succeed != (size_t)-1) return (uint32_t)succeed; } #endif for (; len; --len, ++res, ++tmpWChar, ++tmpShort) { *tmpWChar = (wchar_t)*tmpShort; } return res; } //---------------------------------------------------------------------------// uint32_t getLenShortWcharStr(const WCHAR_T* Source) { uint32_t res = 0; WCHAR_T *tmpShort = (WCHAR_T*)Source; while (*tmpShort++) ++res; return res; } //---------------------------------------------------------------------------// //wchar_t getTypeStringToWchar(const std::string* Data) //{ // std::wstring_convert<std::codecvt_utf8<wchar_t>, wchar_t> converter; // std::wstring wideString = converter.from_bytes(*Data); // // Теперь wideString содержит значение типа wchar_t // return wideString.data(); //} //---------------------------------------------------------------------------//