From c35092bbf03eebe2f86962e16fe9655dd886ae98 Mon Sep 17 00:00:00 2001 From: lijh Date: Tue, 10 Mar 2026 15:26:25 +0800 Subject: [PATCH] first commit --- .gitattributes | 63 ++ .gitignore | 364 +++++++ FTMM_PLM_TO_SAPAPI.sln | 31 + FTMM_PLM_TO_SAPAPI/FTMM_PLM_TO_SAPAPI.vcxproj | 164 +++ FTMM_PLM_TO_SAPAPI/ITK_allHead.h | 47 + FTMM_PLM_TO_SAPAPI/KSM_ERP_BOM.cpp | 948 ++++++++++++++++++ FTMM_PLM_TO_SAPAPI/cJSON.c | 758 ++++++++++++++ FTMM_PLM_TO_SAPAPI/cJSON.h | 149 +++ FTMM_PLM_TO_SAPAPI/connor_itk_util.cpp | 628 ++++++++++++ FTMM_PLM_TO_SAPAPI/connor_itk_util.h | 80 ++ FTMM_PLM_TO_SAPAPI/curl_utils.cxx | 197 ++++ FTMM_PLM_TO_SAPAPI/curl_utils.h | 18 + FTMM_PLM_TO_SAPAPI/main_lib.cpp | 42 + .../register_handler_methods.cpp | 47 + FTMM_PLM_TO_SAPAPI/register_handler_methods.h | 19 + FTMM_PLM_TO_SAPAPI/string_utils.cxx | 289 ++++++ FTMM_PLM_TO_SAPAPI/string_utils.h | 128 +++ 17 files changed, 3972 insertions(+) create mode 100644 .gitattributes create mode 100644 .gitignore create mode 100644 FTMM_PLM_TO_SAPAPI.sln create mode 100644 FTMM_PLM_TO_SAPAPI/FTMM_PLM_TO_SAPAPI.vcxproj create mode 100644 FTMM_PLM_TO_SAPAPI/ITK_allHead.h create mode 100644 FTMM_PLM_TO_SAPAPI/KSM_ERP_BOM.cpp create mode 100644 FTMM_PLM_TO_SAPAPI/cJSON.c create mode 100644 FTMM_PLM_TO_SAPAPI/cJSON.h create mode 100644 FTMM_PLM_TO_SAPAPI/connor_itk_util.cpp create mode 100644 FTMM_PLM_TO_SAPAPI/connor_itk_util.h create mode 100644 FTMM_PLM_TO_SAPAPI/curl_utils.cxx create mode 100644 FTMM_PLM_TO_SAPAPI/curl_utils.h create mode 100644 FTMM_PLM_TO_SAPAPI/main_lib.cpp create mode 100644 FTMM_PLM_TO_SAPAPI/register_handler_methods.cpp create mode 100644 FTMM_PLM_TO_SAPAPI/register_handler_methods.h create mode 100644 FTMM_PLM_TO_SAPAPI/string_utils.cxx create mode 100644 FTMM_PLM_TO_SAPAPI/string_utils.h diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..1ff0c42 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,63 @@ +############################################################################### +# Set default behavior to automatically normalize line endings. +############################################################################### +* text=auto + +############################################################################### +# Set default behavior for command prompt diff. +# +# This is need for earlier builds of msysgit that does not have it on by +# default for csharp files. +# Note: This is only used by command line +############################################################################### +#*.cs diff=csharp + +############################################################################### +# Set the merge driver for project and solution files +# +# Merging from the command prompt will add diff markers to the files if there +# are conflicts (Merging from VS is not affected by the settings below, in VS +# the diff markers are never inserted). Diff markers may cause the following +# file extensions to fail to load in VS. An alternative would be to treat +# these files as binary and thus will always conflict and require user +# intervention with every merge. To do so, just uncomment the entries below +############################################################################### +#*.sln merge=binary +#*.csproj merge=binary +#*.vbproj merge=binary +#*.vcxproj merge=binary +#*.vcproj merge=binary +#*.dbproj merge=binary +#*.fsproj merge=binary +#*.lsproj merge=binary +#*.wixproj merge=binary +#*.modelproj merge=binary +#*.sqlproj merge=binary +#*.wwaproj merge=binary + +############################################################################### +# behavior for image files +# +# image files are treated as binary by default. +############################################################################### +#*.jpg binary +#*.png binary +#*.gif binary + +############################################################################### +# diff behavior for common document formats +# +# Convert binary document formats to text before diffing them. This feature +# is only available from the command line. Turn it on by uncommenting the +# entries below. +############################################################################### +#*.doc diff=astextplain +#*.DOC diff=astextplain +#*.docx diff=astextplain +#*.DOCX diff=astextplain +#*.dot diff=astextplain +#*.DOT diff=astextplain +#*.pdf diff=astextplain +#*.PDF diff=astextplain +#*.rtf diff=astextplain +#*.RTF diff=astextplain diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..efda750 --- /dev/null +++ b/.gitignore @@ -0,0 +1,364 @@ +## Ignore Visual Studio temporary files, build results, and +## files generated by popular Visual Studio add-ons. +## +## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore + +# User-specific files +*.rsuser +*.suo +*.user +*.userosscache +*.sln.docstates + +# User-specific files (MonoDevelop/Xamarin Studio) +*.userprefs + +# Mono auto generated files +mono_crash.* + +# Build results +[Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ +[Rr]eleases/ +x64/ +x86/ +[Ww][Ii][Nn]32/ +[Aa][Rr][Mm]/ +[Aa][Rr][Mm]64/ +bld/ +[Bb]in/ +[Oo]bj/ +[Oo]ut/ +[Ll]og/ +[Ll]ogs/ + +# Visual Studio 2015/2017 cache/options directory +.vs/ +# Uncomment if you have tasks that create the project's static files in wwwroot +#wwwroot/ + +# Visual Studio 2017 auto generated files +Generated\ Files/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +# NUnit +*.VisualState.xml +TestResult.xml +nunit-*.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + +# Benchmark Results +BenchmarkDotNet.Artifacts/ + +# .NET Core +project.lock.json +project.fragment.lock.json +artifacts/ + +# ASP.NET Scaffolding +ScaffoldingReadMe.txt + +# StyleCop +StyleCopReport.xml + +# Files built by Visual Studio +*_i.c +*_p.c +*_h.h +*.ilk +*.meta +*.obj +*.iobj +*.pch +*.pdb +*.ipdb +*.pgc +*.pgd +*.rsp +*.sbr +*.tlb +*.tli +*.tlh +*.tmp +*.tmp_proj +*_wpftmp.csproj +*.log +*.vspscc +*.vssscc +.builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* + +# Visual C++ cache files +ipch/ +*.aps +*.ncb +*.opendb +*.opensdf +*.sdf +*.cachefile +*.VC.db +*.VC.VC.opendb + +# Visual Studio profiler +*.psess +*.vsp +*.vspx +*.sap + +# Visual Studio Trace Files +*.e2e + +# TFS 2012 Local Workspace +$tf/ + +# Guidance Automation Toolkit +*.gpState + +# ReSharper is a .NET coding add-in +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover + +# AxoCover is a Code Coverage Tool +.axoCover/* +!.axoCover/settings.json + +# Coverlet is a free, cross platform Code Coverage Tool +coverage*.json +coverage*.xml +coverage*.info + +# Visual Studio code coverage results +*.coverage +*.coveragexml + +# NCrunch +_NCrunch_* +.*crunch*.local.xml +nCrunchTemp_* + +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ + +# DocProject is a documentation generator add-in +DocProject/buildhelp/ +DocProject/Help/*.HxT +DocProject/Help/*.HxC +DocProject/Help/*.hhc +DocProject/Help/*.hhk +DocProject/Help/*.hhp +DocProject/Help/Html2 +DocProject/Help/html + +# Click-Once directory +publish/ + +# Publish Web Output +*.[Pp]ublish.xml +*.azurePubxml +# Note: Comment the next line if you want to checkin your web deploy settings, +# but database connection strings (with potential passwords) will be unencrypted +*.pubxml +*.publishproj + +# Microsoft Azure Web App publish settings. Comment the next line if you want to +# checkin your Azure Web App publish settings, but sensitive information contained +# in these scripts will be unencrypted +PublishScripts/ + +# NuGet Packages +*.nupkg +# NuGet Symbol Packages +*.snupkg +# The packages folder can be ignored because of Package Restore +**/[Pp]ackages/* +# except build/, which is used as an MSBuild target. +!**/[Pp]ackages/build/ +# Uncomment if necessary however generally it will be regenerated when needed +#!**/[Pp]ackages/repositories.config +# NuGet v3's project.json files produces more ignorable files +*.nuget.props +*.nuget.targets + +# Microsoft Azure Build Output +csx/ +*.build.csdef + +# Microsoft Azure Emulator +ecf/ +rcf/ + +# Windows Store app package directories and files +AppPackages/ +BundleArtifacts/ +Package.StoreAssociation.xml +_pkginfo.txt +*.appx +*.appxbundle +*.appxupload + +# Visual Studio cache files +# files ending in .cache can be ignored +*.[Cc]ache +# but keep track of directories ending in .cache +!?*.[Cc]ache/ + +# Others +ClientBin/ +~$* +*~ +*.dbmdl +*.dbproj.schemaview +*.jfm +*.pfx +*.publishsettings +orleans.codegen.cs + +# Including strong name files can present a security risk +# (https://github.com/github/gitignore/pull/2483#issue-259490424) +#*.snk + +# Since there are multiple workflows, uncomment next line to ignore bower_components +# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) +#bower_components/ + +# RIA/Silverlight projects +Generated_Code/ + +# Backup & report files from converting an old project file +# to a newer Visual Studio version. Backup files are not needed, +# because we have git ;-) +_UpgradeReport_Files/ +Backup*/ +UpgradeLog*.XML +UpgradeLog*.htm +ServiceFabricBackup/ +*.rptproj.bak + +# SQL Server files +*.mdf +*.ldf +*.ndf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings +*.rptproj.rsuser +*- [Bb]ackup.rdl +*- [Bb]ackup ([0-9]).rdl +*- [Bb]ackup ([0-9][0-9]).rdl + +# Microsoft Fakes +FakesAssemblies/ + +# GhostDoc plugin setting file +*.GhostDoc.xml + +# Node.js Tools for Visual Studio +.ntvs_analysis.dat +node_modules/ + +# Visual Studio 6 build log +*.plg + +# Visual Studio 6 workspace options file +*.opt + +# Visual Studio 6 auto-generated workspace file (contains which files were open etc.) +*.vbw + +# Visual Studio LightSwitch build output +**/*.HTMLClient/GeneratedArtifacts +**/*.DesktopClient/GeneratedArtifacts +**/*.DesktopClient/ModelManifest.xml +**/*.Server/GeneratedArtifacts +**/*.Server/ModelManifest.xml +_Pvt_Extensions + +# Paket dependency manager +.paket/paket.exe +paket-files/ + +# FAKE - F# Make +.fake/ + +# CodeRush personal settings +.cr/personal + +# Python Tools for Visual Studio (PTVS) +__pycache__/ +*.pyc + +# Cake - Uncomment if you are using it +# tools/** +# !tools/packages.config + +# Tabs Studio +*.tss + +# Telerik's JustMock configuration file +*.jmconfig + +# BizTalk build output +*.btp.cs +*.btm.cs +*.odx.cs +*.xsd.cs + +# OpenCover UI analysis results +OpenCover/ + +# Azure Stream Analytics local run output +ASALocalRun/ + +# MSBuild Binary and Structured Log +*.binlog + +# NVidia Nsight GPU debugger configuration file +*.nvuser + +# MFractors (Xamarin productivity tool) working folder +.mfractor/ + +# Local History for Visual Studio +.localhistory/ + +# BeatPulse healthcheck temp database +healthchecksdb + +# Backup folder for Package Reference Convert tool in Visual Studio 2017 +MigrationBackup/ + +# Ionide (cross platform F# VS Code tools) working folder +.ionide/ + +# Fody - auto-generated XML schema +FodyWeavers.xsd +/FTMM_PLM_TO_SAPAPI/FTMM_PLM_TO_SAPAPI.vcxproj.filters diff --git a/FTMM_PLM_TO_SAPAPI.sln b/FTMM_PLM_TO_SAPAPI.sln new file mode 100644 index 0000000..ca3df36 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI.sln @@ -0,0 +1,31 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.6.33723.286 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FTMM_PLM_TO_SAPAPI", "FTMM_PLM_TO_SAPAPI\FTMM_PLM_TO_SAPAPI.vcxproj", "{4C7D48C0-184C-4D80-9A32-2A52F828FE82}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Debug|x86 = Debug|x86 + Release|x64 = Release|x64 + Release|x86 = Release|x86 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {4C7D48C0-184C-4D80-9A32-2A52F828FE82}.Debug|x64.ActiveCfg = Debug|x64 + {4C7D48C0-184C-4D80-9A32-2A52F828FE82}.Debug|x64.Build.0 = Debug|x64 + {4C7D48C0-184C-4D80-9A32-2A52F828FE82}.Debug|x86.ActiveCfg = Debug|Win32 + {4C7D48C0-184C-4D80-9A32-2A52F828FE82}.Debug|x86.Build.0 = Debug|Win32 + {4C7D48C0-184C-4D80-9A32-2A52F828FE82}.Release|x64.ActiveCfg = Release|x64 + {4C7D48C0-184C-4D80-9A32-2A52F828FE82}.Release|x64.Build.0 = Release|x64 + {4C7D48C0-184C-4D80-9A32-2A52F828FE82}.Release|x86.ActiveCfg = Release|Win32 + {4C7D48C0-184C-4D80-9A32-2A52F828FE82}.Release|x86.Build.0 = Release|Win32 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {4CEFFB81-DD22-4DD9-9AE8-E679F1DCBCF2} + EndGlobalSection +EndGlobal diff --git a/FTMM_PLM_TO_SAPAPI/FTMM_PLM_TO_SAPAPI.vcxproj b/FTMM_PLM_TO_SAPAPI/FTMM_PLM_TO_SAPAPI.vcxproj new file mode 100644 index 0000000..f6f5edd --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/FTMM_PLM_TO_SAPAPI.vcxproj @@ -0,0 +1,164 @@ + + + + + Debug + Win32 + + + Release + Win32 + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {4c7d48c0-184c-4d80-9a32-2a52f828fe82} + FTMMPLMTOSAPAPI + 10.0 + Comansa_BOM_TO_ERP + + + + Application + true + v143 + Unicode + + + Application + false + v143 + true + Unicode + + + DynamicLibrary + true + v142 + Unicode + + + DynamicLibrary + false + v142 + true + Unicode + + + + + + + + + + + + + + + + + + + + + false + + + + Level3 + true + WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + true + WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + true + true + + + + + Level3 + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions) + true + + + Console + true + + + + + Level3 + true + true + + + WIN32; NDEBUG; _CONSOLE; IPLIB=none ;%(PreprocessorDefinitions) + Default + D:\source\锡压\SignOff_itk\curl\include;D:\source\科曼萨\环境\include;D:\source\科曼萨\环境\include_cpp;%(AdditionalIncludeDirectories) + Default + 4996 + false + + + + Console + true + true + true + D:\source\科曼萨\环境\lib\*.lib;D:\source\科曼萨\环境\curl\lib\*.lib;libcurl_a.lib;Ws2_32.lib;Wldap32.lib;Crypt32.lib;Advapi32.lib;Normaliz.lib;%(AdditionalDependencies) + libuser_exits.ar.lib + D:\source\科曼萨\环境\curl\lib;%(AdditionalLibraryDirectories) + RequireAdministrator + true + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/FTMM_PLM_TO_SAPAPI/ITK_allHead.h b/FTMM_PLM_TO_SAPAPI/ITK_allHead.h new file mode 100644 index 0000000..8f05e25 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/ITK_allHead.h @@ -0,0 +1,47 @@ +#pragma once +#include "connor_itk_util.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "cJSON.h" +#include "curl_utils.h" +#include "string_utils.h" +#include +#include + + +using namespace std; + +#define USERTOKEN "ZPLM_COM_USER:kfUL%B3JmMxKSvSiBgmQXVQzqrwXozmqhewNreFw" +#define XCSRFTOKEN "x-csrf-token: " + +int Comansa_Send_BOM_To_ERP(EPM_action_message_t msg); + +int Comansa_Send_BOM_To_ERP_NEW(EPM_action_message_t msg); diff --git a/FTMM_PLM_TO_SAPAPI/KSM_ERP_BOM.cpp b/FTMM_PLM_TO_SAPAPI/KSM_ERP_BOM.cpp new file mode 100644 index 0000000..a22f5cc --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/KSM_ERP_BOM.cpp @@ -0,0 +1,948 @@ +#include "ITK_allHead.h" + + + +extern "C" int POM_AM__set_application_bypass(logical bypass); + +static int FindTargetTool(tag_t ds_type, const char* ref_name, tag_t* target_tool) +{ + int ifail = 0, tool_count = 0, j = 0, i = 0, no_refs = 0, * export_flags = NULL; + tag_t* tool_list = NULL; + logical found = FALSE; + char** ref_names = NULL; + ITKCALL(AE_ask_datasettype_tools(ds_type, &tool_count, &tool_list)); + for (i = 0; i < tool_count; i++) + { + ifail = AE_ask_tool_oper_refs(ds_type, tool_list[i], ACTION_open, &no_refs, &ref_names, &export_flags); + if (ifail == ITK_ok) + { + for (j = 0; j < no_refs; j++) + { + if (strcmp(ref_names[j], ref_name) == 0 && export_flags[j] == 1) + { + *target_tool = tool_list[i]; + found = TRUE; + break; + } + } + } + MEM_free(export_flags); + MEM_free(ref_names); + + if (found) + break; + } + MEM_free(tool_list); + return ifail; +} + +static int create_dataset(char* ds_type, char* ref_name, char* ds_name, char* fullfilename, tag_t parent_rev, tag_t* dataset) +{ + int ifail = ITK_ok; + tag_t ref_object = NULLTAG, + datasettype = NULLTAG, + new_ds = NULLTAG, + tool = NULLTAG, + folder_tag = NULLTAG; + AE_reference_type_t reference_type; + tag_t new_file_tag = NULLTAG; + IMF_file_t file_descriptor; + char new_ds_name[WSO_name_size_c + 1] = ""; + char* new_file_name; + tag_t relation = NULLTAG; + tag_t spec_relation = NULLTAG; + char* file_ext = NULL; + char* filename = NULL; + + if (fullfilename == NULL) + return ITK_ok; + WriteLog("DEBUG: file path =%s", fullfilename); + + file_ext = strrchr(fullfilename, '.') + 1; + if (file_ext == NULL) + return ITK_ok; + + filename = strrchr(fullfilename, '\\') + 1; + if (filename == NULL) + return ITK_ok; + + new_file_name = USER_new_file_name(new_ds_name, ref_name, file_ext, 0); + //new_file_name = USER_new_file_name(new_ds_name, ref_name, ext, 0); + WriteLog("DEBUG: new_file_name =%s", new_file_name); + + ITKCALL(ifail = IMF_import_file(fullfilename, new_file_name, SS_TEXT, &new_file_tag, &file_descriptor)); + if (ifail != ITK_ok) + return ITK_ok; + + + ITKCALL(IMF_set_original_file_name2(new_file_tag, filename)); + + ITKCALL(IMF_close_file(file_descriptor)); + ITKCALL(AOM_save(new_file_tag)); + ITKCALL(AOM_unlock(new_file_tag)); + + ITKCALL(AE_find_datasettype2(ds_type, &datasettype)); + WriteLog("DEBUG: file name =%s\n", filename); + + ITKCALL(ifail = AE_create_dataset_with_id(datasettype, ds_name, + "", "", "1", &new_ds)); + if (ifail == ITK_ok) + { + WriteLog("DEBUG: create dataset successful\n"); + } + else { + WriteLog("ERROR: create dataset failed\n"); + } + //CALL( AE_create_dataset ( datasettype, ds_name, "", &new_ds)); + if (FindTargetTool(datasettype, ref_name, &tool) != ITK_ok || + tool == NULLTAG) + { + ITKCALL(AE_ask_datasettype_def_tool(datasettype, &tool)); + WriteLog("DEBUG: add ref successful\n"); + }//else{ + // WriteLog("ERROR: ʧ\n"); + // findError =TRUE; + //} + ITKCALL(AE_set_dataset_tool(new_ds, tool)); + ITKCALL(AE_set_dataset_format2(new_ds, TEXT_REF)); + ITKCALL(AE_save_myself(new_ds)); + ITKCALL(AE_add_dataset_named_ref2(new_ds, ref_name, + AE_PART_OF, new_file_tag)); + ITKCALL(AOM_save(new_ds)); + ITKCALL(AOM_unlock(new_ds)); + *dataset = new_ds; + //create relation with item revision + ITKCALL(GRM_find_relation_type(TC_specification_rtype, &spec_relation)); + ITKCALL(ifail = GRM_create_relation(parent_rev, new_ds, spec_relation, NULLTAG, &relation)); + ITKCALL(GRM_save_relation(relation)); + ITKCALL(AOM_unlock(relation)); + if (ifail == ITK_ok) { + WriteLog("DEBUG: dataset add [%s] relation successful", TC_specification_rtype); + } + else { + WriteLog("ERROR: dataset add [%s] relation failed", TC_specification_rtype); + } + return ITK_ok; +} + +void Loop_BOM(tag_t top_bom_line_tag, vector &child_vect, char* secondaryType, vector identify_vec) +{ + printf("start get children info\n"); + int child_count = 0; tag_t* child_tags = NULL; + ITKCALL(BOM_line_ask_all_child_lines(top_bom_line_tag, &child_count, &child_tags)); + if (child_count < 1) { + DOFREE(child_tags); + return; + } + for (int n = 0; n < child_count; n++) + { + tag_t zi_tag = NULLTAG; + ITKCALL(AOM_ask_value_tag(child_tags[n], "bl_line_object", &zi_tag));//ȡBOMLINEİ汾 + char* type = NULL; + ITKCALL(AOM_ask_value_string(zi_tag, "object_type", &type)); + printf("type: %s\n", type); + if (strstr(secondaryType, type) != NULL) { + char* isSend = NULL; + ITKCALL(AOM_ask_value_string(child_tags[n], identify_vec[0].c_str(), &isSend)); + printf("isSend: %s\n", isSend); + if (isSend != NULL) { + if (strstr(identify_vec[1].c_str(), isSend) != NULL) { + child_vect.push_back(child_tags[n]); + } + DOFREE(isSend); + } + } + if (type != NULL) { + DOFREE(type); + } + //ѭ + Loop_BOM(child_tags[n], child_vect, secondaryType, identify_vec); + } + return; +} + + +int Comansa_Send_BOM_To_ERP(EPM_action_message_t msg) { + printf("handle:Comansa_Send_BOM_To_ERP \n"); + int ifail = ITK_ok; + int att_cnt = 0, rev_count = 0; + tag_t rootTask_tag = NULLTAG; + tag_t* attachments = NULL, + * rev_tags = NULL; + time_t timep; + // + int arg_cnt = 0; + char* argflag = NULL, * argvalue = NULL, * arg = NULL; + char logDir[64] = ""; + char primaryType[512] = ""; + char secondaryType[512] = ""; + char identify[64] = ""; + arg_cnt = TC_number_of_arguments(msg.arguments); + if (arg_cnt > 0) + { + POM_AM__set_application_bypass(true); + for (int i = 0; i < arg_cnt; i++) + { + arg = TC_next_argument(msg.arguments); + ifail = ITK_ask_argument_named_value((const char*)arg, &argflag, &argvalue); + if (stricmp(argflag, "logDir") == 0) + { + if (argvalue != NULL) + { + strcpy(logDir, argvalue); + printf("logDir: %s\n", argvalue); + } + } + else if (stricmp(argflag, "primaryType") == 0){ + if (argvalue != NULL) + { + strcpy(primaryType, argvalue); + printf("primaryType: %s\n", argvalue); + } + } + else if (stricmp(argflag, "secondaryType") == 0) { + if (argvalue != NULL) + { + strcpy(secondaryType, argvalue); + printf("secondaryType: %s\n", argvalue); + } + } + else if (stricmp(argflag, "identify") == 0) { + if (argvalue != NULL) + { + strcpy(identify, argvalue); + printf("identify: %s\n", argvalue); + } + } + } + if (argflag != NULL) { + MEM_free(argflag); + argflag = NULL; + } + } + char* url; + ITKCALL(PREF_ask_char_value("Comansa_SendBOMtoERP_URL", 0, &url)); + int value_count = 0; + char** values; + ITKCALL(PREF_ask_char_values("Comansa_SendBOMtoERP_Config", &value_count, &values)); + vector identify_vec; + if (strstr(identify, ":") != NULL) { + Split(identify, ":", identify_vec); + } + char* log_file = NULL; + char* QZ_SAP_BOM = (char*)malloc(sizeof("Comansa_ERP_BOM_LOG")); + strcpy(QZ_SAP_BOM, "Comansa_ERP_BOM_LOG"); + CreateLogFile2(QZ_SAP_BOM, &log_file, logDir); + time(&timep); + WriteLog("**********************create log file,Date%s **********************\n", ctime(&timep)); + EPM_ask_root_task(msg.task, &rootTask_tag); + EPM_ask_attachments(rootTask_tag, EPM_target_attachment, &att_cnt, &attachments); + WriteLog("get target object ,num : %d\n", att_cnt); + if (att_cnt > 0) { + vector child_vect; + for (int i = 0; i < att_cnt; i++) { + char* objtype = NULL; + ITKCALL(AOM_ask_value_string(attachments[i], "object_type", &objtype)); + WriteLog("objtype : %s\n", objtype); + if (strstr(primaryType, objtype) != NULL) { + tag_t bom_window_tag = NULLTAG; + tag_t topLine = NULLTAG;//bomline + ITKCALL(BOM_create_window(&bom_window_tag)); + ITKCALL(BOM_set_window_top_line(bom_window_tag, NULLTAG, attachments[i], NULLTAG, &topLine)); + + Loop_BOM(topLine, child_vect, secondaryType, identify_vec); + tag_t item = NULLTAG, master_form_rel_type = NULLTAG; + int form_count = 0; + tag_t* form_list = NULL, master_form = NULLTAG; + ITKCALL(GRM_find_relation_type(TC_master_form_rtype, &master_form_rel_type)); + ITKCALL(GRM_list_secondary_objects_only(attachments[i], master_form_rel_type, &form_count, &form_list)); + ITKCALL(ITEM_ask_item_of_rev(attachments[i], &item)); + master_form = form_list[0]; + if (form_list != NULL) { + DOFREE(form_list); + } + cJSON* json = cJSON_CreateObject(); + if (strstr(values[0], ";") != NULL) { + vector attrs_vec; + Split(values[0], ";", attrs_vec); + for (int j = 0; j < attrs_vec.size(); j++) + { + if (strstr(attrs_vec[j].c_str(), "=") != NULL) { + vector attr_vec; + Split(attrs_vec[j].c_str(), "=", attr_vec); + if (strstr(attr_vec[1].c_str(), ".") != NULL) { + vector vec; + Split(attr_vec[1].c_str(), ".", vec); + char* value = NULL; + if (strcmp(vec[0].c_str(), "item") == 0) { + ITKCALL(AOM_UIF_ask_value(item, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "rev") == 0) { + ITKCALL(AOM_UIF_ask_value(attachments[i], vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "form") == 0) { + ITKCALL(AOM_UIF_ask_value(master_form, vec[1].c_str(), &value)); + } + cJSON_AddStringToObject(json, attr_vec[0].c_str(), value); + if (value != NULL) { + DOFREE(value); + } + } + else { + cJSON_AddStringToObject(json, attr_vec[0].c_str(), attr_vec[1].c_str()); + } + } + } + } + else { + if (strstr(values[0], "=") != NULL) { + vector attr_vec; + Split(values[0], "=", attr_vec); + if (strstr(attr_vec[1].c_str(), ".") != NULL) { + vector vec; + Split(attr_vec[1].c_str(), ".", vec); + char* value = NULL; + if (strcmp(vec[0].c_str(), "item") == 0) { + ITKCALL(AOM_UIF_ask_value(item, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "rev") == 0) { + ITKCALL(AOM_UIF_ask_value(attachments[i], vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "form") == 0) { + ITKCALL(AOM_UIF_ask_value(master_form, vec[1].c_str(), &value)); + } + cJSON_AddStringToObject(json, attr_vec[0].c_str(), value); + if (value != NULL) { + DOFREE(value); + } + } + else { + cJSON_AddStringToObject(json, attr_vec[0].c_str(), attr_vec[1].c_str()); + } + } + } + + if (strstr(values[1], "|") != NULL) { + vector json_vec; + Split(values[1], "|", json_vec); + cJSON* to_BillOfMaterialItem_arr = cJSON_CreateArray(); + for (int n = 0; n < child_vect.size(); n++) + { + tag_t child_line_tag = child_vect[n]; + tag_t zi_item = NULLTAG; + tag_t zi_rev = NULLTAG; + int zi_form_count = 0; + tag_t* zi_form_list = NULL, zi_master_form = NULLTAG; + ITKCALL(AOM_ask_value_tag(child_line_tag, "bl_line_object", &zi_rev));//ȡBOMLINEİ汾 + ITKCALL(GRM_list_secondary_objects_only(zi_rev, master_form_rel_type, &zi_form_count, &zi_form_list)); + zi_master_form = zi_form_list[0]; + if (zi_form_list != NULL) { + DOFREE(zi_form_list); + } + ITKCALL(ITEM_ask_item_of_rev(zi_rev, &zi_item)); + cJSON* to_BillOfMaterialItem_obj = cJSON_CreateObject(); + if (strstr(json_vec[1].c_str(), ";") != NULL) { + vector attrs_vec; + Split(json_vec[1].c_str(), ";", attrs_vec); + for (int j = 0; j < attrs_vec.size(); j++) + { + if (strstr(attrs_vec[j].c_str(), "=") != NULL) { + vector attr_vec; + Split(attrs_vec[j].c_str(), "=", attr_vec); + if (strstr(attr_vec[1].c_str(), ".") != NULL) { + vector vec; + Split(attr_vec[1].c_str(), ".", vec); + char* value = NULL; + if (strcmp(vec[0].c_str(), "item") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_item, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "rev") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_rev, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "form") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_master_form, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "bomline") == 0) { + ITKCALL(AOM_UIF_ask_value(child_line_tag, vec[1].c_str(), &value)); + } + if (strstr(vec[1].c_str(), "bl_quantity") != NULL) { + if (value == NULL || strcmp("", value) == 0 || strcmp(" ", value) == 0) { + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), 1); + } + else { + double d = std::stod(value); + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), d); + } + } + else { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), value); + } + if (value != NULL) { + DOFREE(value); + } + } + else { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), attr_vec[1].c_str()); + } + } + } + } + else { + if (strstr(json_vec[1].c_str(), "=") != NULL) { + vector attr_vec; + Split(json_vec[1].c_str(), "=", attr_vec); + if (strstr(attr_vec[1].c_str(), ".") != NULL) { + vector vec; + Split(attr_vec[1].c_str(), ".", vec); + char* value = NULL; + if (strcmp(vec[0].c_str(), "item") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_item, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "rev") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_rev, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "form") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_master_form, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "bomline") == 0) { + ITKCALL(AOM_UIF_ask_value(child_line_tag, vec[1].c_str(), &value)); + } + if (strstr(vec[1].c_str(),"bl_quantity") != NULL) { + if (value == NULL || strcmp("",value) == 0 || strcmp(" ", value) == 0) { + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), 1); + } + else { + double d = std::stod(value); + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), d); + } + } + else { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), value); + } + if (value != NULL) { + DOFREE(value); + } + } + else { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), attr_vec[1].c_str()); + } + } + } + cJSON_AddItemToArray(to_BillOfMaterialItem_arr, to_BillOfMaterialItem_obj); + + } + cJSON_AddItemToObject(json, json_vec[0].c_str(), to_BillOfMaterialItem_arr); + } + clock_t start, finish; + double total_time; + string err_msg; + long code = 0; + char* json_to_char = NULL; + json_to_char = cJSON_Print(json); + WriteLog("send json: %s\n", json_to_char); + start = clock(); + string res = postJSON(url, json_to_char, code, err_msg); + WriteLog("Code: %ldmessage-> %s\n", code, res.c_str()); + string res_value = ""; + if (code == 200) + { + WriteLog("BOM send successful\n"); + res_value = "Sent"; + } + else + { + WriteLog("BOM send failed,message: %s \n", res.c_str()); + res_value = "No"; + tag_t user = NULLTAG;//ǰû + char* userName; + printf("get user\n"); + int s = POM_get_user(&userName, &user); + tag_t newds = NULLTAG; + char path[128] = "\0"; + strcat(path, getenv("TEMP")); + strcat(path, "\\"); + strcat(path, "bomSendErp.txt"); + FILE* fpWrite = fopen(path, "w"); + fprintf(fpWrite, "%s", res.c_str()); + fclose(fpWrite); + ifail = create_dataset("Text", "Text", "bomSendErp", path, + attachments[i], &newds); + + tag_t envelope = NULLTAG; + ITKCALL(MAIL_create_envelope("Send to ERP Failed", "Send to ERP Failed, please see bomSendErp.txt ", &envelope)); + ITKCALL(MAIL_add_envelope_receiver(envelope, user)); + ITKCALL(FL_insert(envelope, attachments[i], 0)); + ITKCALL(FL_insert(envelope, newds, 0)); + ITKCALL (AOM_save( envelope )); + ITKCALL(MAIL_send_envelope(envelope)); + // ɾļ + if (strlen(path) > 0) { + remove(path); + } + } + for (int j = 0; j < child_vect.size(); j++) + { + tag_t child_line = child_vect[j]; + int attr = 0; + //ITKCALL(BOM_line_look_up_attribute(identify_vec[0].c_str(), &attr)); + //ITKCALL(BOM_line_set_attribute_string(child_line, attr, res_value.c_str())); + ITKCALL(AOM_set_value_string(child_line, identify_vec[0].c_str(), res_value.c_str())); + } + /* if (json_to_char != NULL) { + DOFREE(json_to_char); + } + printf("5555555\n");*/ + finish = clock(); + total_time = (double)(finish - start) / CLOCKS_PER_SEC; //λ + WriteLog("******api time cost %f seconds******\n", total_time); + ITKCALL(BOM_save_window(bom_window_tag)); + BOM_close_window(bom_window_tag); + } + if (objtype != NULL) { + DOFREE(objtype); + } + } + CloseLog(); + POM_AM__set_application_bypass(false); + } + return ifail; +} + + + + +void Loop_BOM_NEW(tag_t top_bom_line_tag, vector& child_vect, char* bottomType, cJSON* json,char* value, tag_t master_form_rel_type,int index) +{ + printf("start get children info\n"); + int child_count = 0; tag_t* child_tags = NULL; + ITKCALL(BOM_line_ask_all_child_lines(top_bom_line_tag, &child_count, &child_tags)); + if (child_count < 1) { + DOFREE(child_tags); + return; + } + if (strstr(value, "|") != NULL) { + vector json_vec; + Split(value, "|", json_vec); + cJSON* to_BillOfMaterialItem_arr = cJSON_CreateArray(); + for (int n = 0; n < child_count; n++) + { + tag_t child_line_tag = child_tags[n]; + tag_t zi_item = NULLTAG; + tag_t zi_rev = NULLTAG; + int zi_form_count = 0; + tag_t* zi_form_list = NULL, zi_master_form = NULLTAG; + ITKCALL(AOM_ask_value_tag(child_line_tag, "bl_line_object", &zi_rev));//ȡBOMLINEİ汾 + ITKCALL(GRM_list_secondary_objects_only(zi_rev, master_form_rel_type, &zi_form_count, &zi_form_list)); + zi_master_form = zi_form_list[0]; + if (zi_form_list != NULL) { + DOFREE(zi_form_list); + } + ITKCALL(ITEM_ask_item_of_rev(zi_rev, &zi_item)); + cJSON* to_BillOfMaterialItem_obj = cJSON_CreateObject(); + if (strstr(json_vec[1].c_str(), ";") != NULL) { + vector attrs_vec; + Split(json_vec[1].c_str(), ";", attrs_vec); + for (int j = 0; j < attrs_vec.size(); j++) + { + if (strstr(attrs_vec[j].c_str(), "=") != NULL) { + vector attr_vec; + Split(attrs_vec[j].c_str(), "=", attr_vec); + if (strstr(attr_vec[1].c_str(), ".") != NULL) { + vector vec; + Split(attr_vec[1].c_str(), ".", vec); + char* value = NULL; + if (strcmp(vec[0].c_str(), "item") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_item, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "rev") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_rev, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "form") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_master_form, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "bomline") == 0) { + ITKCALL(AOM_UIF_ask_value(child_line_tag, vec[1].c_str(), &value)); + } + if (strstr(vec[1].c_str(), "bl_quantity") != NULL) { + if (value == NULL || strcmp("", value) == 0 || strcmp(" ", value) == 0) { + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), 1); + } + else { + double d = std::stod(value); + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), d); + } + } + else { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), value); + } + if (value != NULL) { + DOFREE(value); + } + } + else { + if (strcmp("level", attr_vec[0].c_str()) == 0) { + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), index); + }else if (strcmp("NULL", attr_vec[1].c_str()) == 0) { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), ""); + } + else { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), attr_vec[1].c_str()); + } + } + } + } + } + else { + if (strstr(json_vec[1].c_str(), "=") != NULL) { + vector attr_vec; + Split(json_vec[1].c_str(), "=", attr_vec); + if (strstr(attr_vec[1].c_str(), ".") != NULL) { + vector vec; + Split(attr_vec[1].c_str(), ".", vec); + char* value = NULL; + if (strcmp(vec[0].c_str(), "item") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_item, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "rev") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_rev, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "form") == 0) { + ITKCALL(AOM_UIF_ask_value(zi_master_form, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "bomline") == 0) { + ITKCALL(AOM_UIF_ask_value(child_line_tag, vec[1].c_str(), &value)); + } + if (strstr(vec[1].c_str(), "bl_quantity") != NULL) { + if (value == NULL || strcmp("", value) == 0 || strcmp(" ", value) == 0) { + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), 1); + } + else { + double d = std::stod(value); + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), d); + } + } + else { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), value); + } + if (value != NULL) { + DOFREE(value); + } + } + else { + if (strcmp("level", attr_vec[1].c_str()) == 0) { + cJSON_AddNumberToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), index); + } + else if (strcmp("NULL", attr_vec[1].c_str()) == 0) { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), ""); + } + else { + cJSON_AddStringToObject(to_BillOfMaterialItem_obj, attr_vec[0].c_str(), attr_vec[1].c_str()); + } + } + } + } + cJSON_AddItemToArray(to_BillOfMaterialItem_arr, to_BillOfMaterialItem_obj); + child_vect.push_back(child_tags[n]); + char* type = NULL; + ITKCALL(AOM_ask_value_string(zi_rev, "object_type", &type)); + if (strstr(bottomType, type) == NULL) { + //ѭ + Loop_BOM_NEW(child_tags[n], child_vect, bottomType, to_BillOfMaterialItem_obj, value, master_form_rel_type, index + 1); + } + if (type != NULL) { + DOFREE(type); + } + } + cJSON_AddItemToObject(json, json_vec[0].c_str(), to_BillOfMaterialItem_arr); + } + return; +} + +int Comansa_Send_BOM_To_ERP_NEW(EPM_action_message_t msg) { + printf("handle:Comansa_Send_BOM_To_ERP_NEW \n"); + int ifail = ITK_ok; + int att_cnt = 0, rev_count = 0; + tag_t rootTask_tag = NULLTAG; + tag_t* attachments = NULL, + * rev_tags = NULL; + time_t timep; + // + int arg_cnt = 0; + char* argflag = NULL, * argvalue = NULL, * arg = NULL; + char logDir[64] = ""; + char topType[512] = ""; + char bottomType[512] = ""; + char option[64] = ""; + char isUpdate[16] = ""; + arg_cnt = TC_number_of_arguments(msg.arguments); + if (arg_cnt > 0) + { + POM_AM__set_application_bypass(true); + for (int i = 0; i < arg_cnt; i++) + { + arg = TC_next_argument(msg.arguments); + ifail = ITK_ask_argument_named_value((const char*)arg, &argflag, &argvalue); + if (stricmp(argflag, "logDir") == 0) + { + if (argvalue != NULL) + { + strcpy(logDir, argvalue); + printf("logDir: %s\n", argvalue); + } + } + else if (stricmp(argflag, "topType") == 0) { + if (argvalue != NULL) + { + strcpy(topType, argvalue); + printf("topType: %s\n", argvalue); + } + } + else if (stricmp(argflag, "bottomType") == 0) { + if (argvalue != NULL) + { + strcpy(bottomType, argvalue); + printf("bottomType: %s\n", argvalue); + } + } + else if (stricmp(argflag, "Option") == 0) { + if (argvalue != NULL) + { + strcpy(option, argvalue); + printf("option: %s\n", argvalue); + } + } + else if (stricmp(argflag, "IfUpdateIdentify") == 0) { + if (argvalue != NULL) + { + strcpy(isUpdate, argvalue); + printf("isUpdate: %s\n", argvalue); + } + } + } + if (argflag != NULL) { + MEM_free(argflag); + argflag = NULL; + } + } + char* url; + ITKCALL(PREF_ask_char_value("Comansa_SendBOMtoERP_URL_New", 0, &url)); + int value_count = 0; + char** values; + ITKCALL(PREF_ask_char_values(option, &value_count, &values)); + char* log_file = NULL; + char* QZ_SAP_BOM = (char*)malloc(sizeof("Comansa_ERP_BOM_NEW_LOG")); + strcpy(QZ_SAP_BOM, "Comansa_ERP_BOM_NEW_LOG"); + CreateLogFile2(QZ_SAP_BOM, &log_file, logDir); + time(&timep); + WriteLog("**********************create log file,Date%s **********************\n", ctime(&timep)); + EPM_ask_root_task(msg.task, &rootTask_tag); + tag_t processUser = NULLTAG; + char* processUserName = NULL; + ITKCALL(AOM_ask_value_tag(rootTask_tag, "owning_user", &processUser)); + ITKCALL(AOM_ask_value_string(processUser, "user_id", &processUserName)); + EPM_ask_attachments(rootTask_tag, EPM_target_attachment, &att_cnt, &attachments); + WriteLog("get target object ,num : %d\n", att_cnt); + tag_t user = NULLTAG;//ǰû + char* userName; + WriteLog("get user\n"); + int s = POM_get_user(&userName, &user); + if (att_cnt > 0) { + vector child_vect; + for (int i = 0; i < att_cnt; i++) { + char* objtype = NULL; + ITKCALL(AOM_ask_value_string(attachments[i], "object_type", &objtype)); + WriteLog("objtype : %s\n", objtype); + WriteLog("topType : %s\n", topType); + if (strstr(topType, objtype) != NULL || strcmp(topType, objtype) == 0) { + WriteLog("objtype is matching \n"); + tag_t bom_window_tag = NULLTAG; + tag_t topLine = NULLTAG;//bomline + ITKCALL(BOM_create_window(&bom_window_tag)); + ITKCALL(BOM_set_window_top_line(bom_window_tag, NULLTAG, attachments[i], NULLTAG, &topLine)); + + tag_t item = NULLTAG, master_form_rel_type = NULLTAG; + int form_count = 0; + tag_t* form_list = NULL, master_form = NULLTAG; + ITKCALL(GRM_find_relation_type(TC_master_form_rtype, &master_form_rel_type)); + ITKCALL(GRM_list_secondary_objects_only(attachments[i], master_form_rel_type, &form_count, &form_list)); + ITKCALL(ITEM_ask_item_of_rev(attachments[i], &item)); + master_form = form_list[0]; + if (form_list != NULL) { + DOFREE(form_list); + } + int index = 1; + cJSON* json = cJSON_CreateObject(); + if (strstr(values[0], ";") != NULL) { + vector attrs_vec; + Split(values[0], ";", attrs_vec); + for (int j = 0; j < attrs_vec.size(); j++) + { + if (strstr(attrs_vec[j].c_str(), "=") != NULL) { + vector attr_vec; + Split(attrs_vec[j].c_str(), "=", attr_vec); + if (strstr(attr_vec[1].c_str(), ".") != NULL) { + vector vec; + Split(attr_vec[1].c_str(), ".", vec); + char* value = NULL; + if (strcmp(vec[0].c_str(), "item") == 0) { + ITKCALL(AOM_UIF_ask_value(item, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "rev") == 0) { + ITKCALL(AOM_UIF_ask_value(attachments[i], vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "form") == 0) { + ITKCALL(AOM_UIF_ask_value(master_form, vec[1].c_str(), &value)); + } + cJSON_AddStringToObject(json, attr_vec[0].c_str(), value); + if (value != NULL) { + DOFREE(value); + } + } + else { + if (strcmp("processowner", attr_vec[1].c_str()) == 0) { + WriteLog("attr = %s", attr_vec[1].c_str()); + WriteLog("value = %s", processUserName); + cJSON_AddStringToObject(json, attr_vec[0].c_str(), processUserName); + } + else if (strcmp("currentuser", attr_vec[1].c_str()) == 0) { + cJSON_AddStringToObject(json, attr_vec[0].c_str(), userName); + } + else if (strcmp("level", attr_vec[1].c_str()) == 0) { + cJSON_AddNumberToObject(json, attr_vec[0].c_str(), index); + WriteLog("attr = %s", attr_vec[1].c_str()); + WriteLog("value = %d", index); + } + else { + cJSON_AddStringToObject(json, attr_vec[0].c_str(), attr_vec[1].c_str()); + } + } + } + } + } + else { + if (strstr(values[0], "=") != NULL) { + vector attr_vec; + Split(values[0], "=", attr_vec); + if (strstr(attr_vec[1].c_str(), ".") != NULL) { + vector vec; + Split(attr_vec[1].c_str(), ".", vec); + char* value = NULL; + if (strcmp(vec[0].c_str(), "item") == 0) { + ITKCALL(AOM_UIF_ask_value(item, vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "rev") == 0) { + ITKCALL(AOM_UIF_ask_value(attachments[i], vec[1].c_str(), &value)); + } + else if (strcmp(vec[0].c_str(), "form") == 0) { + ITKCALL(AOM_UIF_ask_value(master_form, vec[1].c_str(), &value)); + } + cJSON_AddStringToObject(json, attr_vec[0].c_str(), value); + if (value != NULL) { + DOFREE(value); + } + } + else { + if (strcmp("processowner", attr_vec[1].c_str()) == 0) { + cJSON_AddStringToObject(json, attr_vec[0].c_str(), processUserName); + } + else if (strcmp("currentuser", attr_vec[1].c_str()) == 0) { + cJSON_AddStringToObject(json, attr_vec[0].c_str(), userName); + } + else if (strcmp("level", attr_vec[1].c_str()) == 0) { + cJSON_AddNumberToObject(json, attr_vec[0].c_str(), index); + } + else { + cJSON_AddStringToObject(json, attr_vec[0].c_str(), attr_vec[1].c_str()); + } + } + } + } + Loop_BOM_NEW(topLine, child_vect, bottomType,json, values[1], master_form_rel_type,index + 1); + clock_t start, finish; + double total_time; + string err_msg; + long code = 0; + char* json_to_char = NULL; + json_to_char = cJSON_Print(json); + WriteLog("send json: %s\n", json_to_char); + start = clock(); + string res = postJSON(url, json_to_char, code, err_msg); + WriteLog("Code: %ldmessage-> %s\n", code, res.c_str()); + string res_value = ""; + if (code == 200) + { + WriteLog("BOM send successful\n"); + res_value = "Sent"; + } + else + { + WriteLog("BOM send failed,message: %s \n", res.c_str()); + res_value = "No"; + tag_t newds = NULLTAG; + char path[128] = "\0"; + strcat(path, getenv("TEMP")); + strcat(path, "\\"); + strcat(path, "bomSendErp.txt"); + FILE* fpWrite = fopen(path, "w"); + fprintf(fpWrite, "%s", res.c_str()); + fclose(fpWrite); + ifail = create_dataset("Text", "Text", "bomSendErp", path, + attachments[i], &newds); + + tag_t envelope = NULLTAG; + ITKCALL(MAIL_create_envelope("Send to ERP Failed", "Send to ERP Failed, please see bomSendErp.txt ", &envelope)); + ITKCALL(MAIL_add_envelope_receiver(envelope, user)); + ITKCALL(FL_insert(envelope, attachments[i], 0)); + ITKCALL(FL_insert(envelope, newds, 0)); + ITKCALL(AOM_save(envelope)); + ITKCALL(MAIL_send_envelope(envelope)); + // // ɾļ + if (strlen(path) > 0) { + remove(path); + } + } + if (strcmp("true", isUpdate) == 0) { + for (int j = 0; j < child_vect.size(); j++) + { + tag_t child_line = child_vect[j]; + int attr = 0; + // ITKCALL(BOM_line_look_up_attribute("CM4_SendToERPStatus", &attr)); + // ITKCALL(BOM_line_set_attribute_string(child_line, attr, res_value.c_str())); + ITKCALL(AOM_set_value_string(child_line, "CM4_SendToERPStatus", res_value.c_str())); + } + } + + ///* if (json_to_char != NULL) { + // DOFREE(json_to_char); + // } + // printf("5555555\n");*/ + finish = clock(); + total_time = (double)(finish - start) / CLOCKS_PER_SEC; //λ + WriteLog("******api time cost %f seconds******\n", total_time); + ITKCALL(BOM_save_window(bom_window_tag)); + BOM_close_window(bom_window_tag); + } + else { + WriteLog("objtype is not matching \n"); + } + if (objtype != NULL) { + DOFREE(objtype); + } + } + CloseLog(); + POM_AM__set_application_bypass(false); + } + if (userName != NULL) { + DOFREE(userName); + } + if (processUserName != NULL) { + DOFREE(processUserName); + } + if (url != NULL) { + DOFREE(url); + } + return ifail; +} + + + diff --git a/FTMM_PLM_TO_SAPAPI/cJSON.c b/FTMM_PLM_TO_SAPAPI/cJSON.c new file mode 100644 index 0000000..b4d6136 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/cJSON.c @@ -0,0 +1,758 @@ +#pragma once +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +#include +#include +#include +#include +#include +#include +#include +#include "cJSON.h" +#pragma warning(disable : 4996) +static const char* ep; + +const char* cJSON_GetErrorPtr(void) { return ep; } + +static int cJSON_strcasecmp(const char* s1, const char* s2) +{ + if (!s1) return (s1 == s2) ? 0 : 1;if (!s2) return 1; + for (; tolower(*s1) == tolower(*s2); ++s1, ++s2) if (*s1 == 0) return 0; + return tolower(*(const unsigned char*)s1) - tolower(*(const unsigned char*)s2); +} + +static void* (*cJSON_malloc)(size_t sz) = malloc; +static void (*cJSON_free)(void* ptr) = free; + +static char* cJSON_strdup(const char* str) +{ + size_t len; + char* copy; + + len = strlen(str) + 1; + if (!(copy = (char*)cJSON_malloc(len))) return 0; + memcpy(copy, str, len); + return copy; +} + +void cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (!hooks) { /* Reset hooks */ + cJSON_malloc = malloc; + cJSON_free = free; + return; + } + + cJSON_malloc = (hooks->malloc_fn) ? hooks->malloc_fn : malloc; + cJSON_free = (hooks->free_fn) ? hooks->free_fn : free; +} + +/* Internal constructor. */ +static cJSON* cJSON_New_Item(void) +{ + cJSON* node = (cJSON*)cJSON_malloc(sizeof(cJSON)); + if (node) memset(node, 0, sizeof(cJSON)); + return node; +} + +/* Delete a cJSON structure. */ +void cJSON_Delete(cJSON* c) +{ + cJSON* next; + while (c) + { + next = c->next; + if (!(c->type & cJSON_IsReference) && c->child) cJSON_Delete(c->child); + if (!(c->type & cJSON_IsReference) && c->valuestring) cJSON_free(c->valuestring); + if (!(c->type & cJSON_StringIsConst) && c->string) cJSON_free(c->string); + cJSON_free(c); + c = next; + } +} + +/* Parse the input text to generate a number, and populate the result into item. */ +static const char* parse_number(cJSON* item, const char* num) +{ + double n = 0, sign = 1, scale = 0;int subscale = 0, signsubscale = 1; + + if (*num == '-') sign = -1, num++; /* Has sign? */ + if (*num == '0') num++; /* is zero */ + if (*num >= '1' && *num <= '9') do n = (n * 10.0) + (*num++ - '0'); while (*num >= '0' && *num <= '9'); /* Number? */ + if (*num == '.' && num[1] >= '0' && num[1] <= '9') { num++; do n = (n * 10.0) + (*num++ - '0'), scale--; while (*num >= '0' && *num <= '9'); } /* Fractional part? */ + if (*num == 'e' || *num == 'E') /* Exponent? */ + { + num++;if (*num == '+') num++; else if (*num == '-') signsubscale = -1, num++; /* With sign? */ + while (*num >= '0' && *num <= '9') subscale = (subscale * 10) + (*num++ - '0'); /* Number? */ + } + + n = sign * n * pow(10.0, (scale + subscale * signsubscale)); /* number = +/- number.fraction * 10^+/- exponent */ + + item->valuedouble = n; + item->valueint = (int)n; + item->type = cJSON_Number; + return num; +} + +static int pow2gt(int x) { --x; x |= x >> 1; x |= x >> 2; x |= x >> 4; x |= x >> 8; x |= x >> 16; return x + 1; } + +typedef struct { char* buffer; int length; int offset; } printbuffer; + +static char* ensure(printbuffer* p, int needed) +{ + char* newbuffer;int newsize; + if (!p || !p->buffer) return 0; + needed += p->offset; + if (needed <= p->length) return p->buffer + p->offset; + + newsize = pow2gt(needed); + newbuffer = (char*)cJSON_malloc(newsize); + if (!newbuffer) { cJSON_free(p->buffer);p->length = 0, p->buffer = 0;return 0; } + if (newbuffer) memcpy(newbuffer, p->buffer, p->length); + cJSON_free(p->buffer); + p->length = newsize; + p->buffer = newbuffer; + return newbuffer + p->offset; +} + +static int update(printbuffer* p) +{ + char* str; + if (!p || !p->buffer) return 0; + str = p->buffer + p->offset; + return p->offset + strlen(str); +} + +/* Render the number nicely from the given item into a string. */ +static char* print_number(cJSON* item, printbuffer* p) +{ + char* str = 0; + double d = item->valuedouble; + if (d == 0) + { + if (p) str = ensure(p, 2); + else str = (char*)cJSON_malloc(2); /* special case for 0. */ + if (str) strcpy(str, "0"); + } + else if (fabs(((double)item->valueint) - d) <= DBL_EPSILON && d <= INT_MAX && d >= INT_MIN) + { + if (p) str = ensure(p, 21); + else str = (char*)cJSON_malloc(21); /* 2^64+1 can be represented in 21 chars. */ + if (str) sprintf(str, "%d", item->valueint); + } + else + { + if (p) str = ensure(p, 64); + else str = (char*)cJSON_malloc(64); /* This is a nice tradeoff. */ + if (str) + { + if (fabs(floor(d) - d) <= DBL_EPSILON && fabs(d) < 1.0e60)sprintf(str, "%.0f", d); + else if (fabs(d) < 1.0e-6 || fabs(d) > 1.0e9) sprintf(str, "%e", d); + else sprintf(str, "%f", d); + } + } + return str; +} + +static unsigned parse_hex4(const char* str) +{ + unsigned h = 0; + if (*str >= '0' && *str <= '9') h += (*str) - '0'; else if (*str >= 'A' && *str <= 'F') h += 10 + (*str) - 'A'; else if (*str >= 'a' && *str <= 'f') h += 10 + (*str) - 'a'; else return 0; + h = h << 4;str++; + if (*str >= '0' && *str <= '9') h += (*str) - '0'; else if (*str >= 'A' && *str <= 'F') h += 10 + (*str) - 'A'; else if (*str >= 'a' && *str <= 'f') h += 10 + (*str) - 'a'; else return 0; + h = h << 4;str++; + if (*str >= '0' && *str <= '9') h += (*str) - '0'; else if (*str >= 'A' && *str <= 'F') h += 10 + (*str) - 'A'; else if (*str >= 'a' && *str <= 'f') h += 10 + (*str) - 'a'; else return 0; + h = h << 4;str++; + if (*str >= '0' && *str <= '9') h += (*str) - '0'; else if (*str >= 'A' && *str <= 'F') h += 10 + (*str) - 'A'; else if (*str >= 'a' && *str <= 'f') h += 10 + (*str) - 'a'; else return 0; + return h; +} + +/* Parse the input text into an unescaped cstring, and populate item. */ +static const unsigned char firstByteMark[7] = { 0x00, 0x00, 0xC0, 0xE0, 0xF0, 0xF8, 0xFC }; +static const char* parse_string(cJSON* item, const char* str) +{ + const char* ptr = str + 1;char* ptr2;char* out;int len = 0;unsigned uc, uc2; + if (*str != '\"') { ep = str;return 0; } /* not a string! */ + + while (*ptr != '\"' && *ptr && ++len) if (*ptr++ == '\\') ptr++; /* Skip escaped quotes. */ + + out = (char*)cJSON_malloc(len + 1); /* This is how long we need for the string, roughly. */ + if (!out) return 0; + + ptr = str + 1;ptr2 = out; + while (*ptr != '\"' && *ptr) + { + if (*ptr != '\\') *ptr2++ = *ptr++; + else + { + ptr++; + switch (*ptr) + { + case 'b': *ptr2++ = '\b'; break; + case 'f': *ptr2++ = '\f'; break; + case 'n': *ptr2++ = '\n'; break; + case 'r': *ptr2++ = '\r'; break; + case 't': *ptr2++ = '\t'; break; + case 'u': /* transcode utf16 to utf8. */ + uc = parse_hex4(ptr + 1);ptr += 4; /* get the unicode char. */ + + if ((uc >= 0xDC00 && uc <= 0xDFFF) || uc == 0) break; /* check for invalid. */ + + if (uc >= 0xD800 && uc <= 0xDBFF) /* UTF16 surrogate pairs. */ + { + if (ptr[1] != '\\' || ptr[2] != 'u') break; /* missing second-half of surrogate. */ + uc2 = parse_hex4(ptr + 3);ptr += 6; + if (uc2 < 0xDC00 || uc2>0xDFFF) break; /* invalid second-half of surrogate. */ + uc = 0x10000 + (((uc & 0x3FF) << 10) | (uc2 & 0x3FF)); + } + + len = 4;if (uc < 0x80) len = 1;else if (uc < 0x800) len = 2;else if (uc < 0x10000) len = 3; ptr2 += len; + + switch (len) { + case 4: *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; + case 3: *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; + case 2: *--ptr2 = ((uc | 0x80) & 0xBF); uc >>= 6; + case 1: *--ptr2 = (uc | firstByteMark[len]); + } + ptr2 += len; + break; + default: *ptr2++ = *ptr; break; + } + ptr++; + } + } + *ptr2 = 0; + if (*ptr == '\"') ptr++; + item->valuestring = out; + item->type = cJSON_String; + return ptr; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static char* print_string_ptr(const char* str, printbuffer* p) +{ + const char* ptr;char* ptr2, * out;int len = 0, flag = 0;unsigned char token; + + for (ptr = str;*ptr;ptr++) flag |= ((*ptr > 0 && *ptr < 32) || (*ptr == '\"') || (*ptr == '\\')) ? 1 : 0; + if (!flag) + { + len = ptr - str; + if (p) out = ensure(p, len + 3); + else out = (char*)cJSON_malloc(len + 3); + if (!out) return 0; + ptr2 = out;*ptr2++ = '\"'; + strcpy(ptr2, str); + ptr2[len] = '\"'; + ptr2[len + 1] = 0; + return out; + } + + if (!str) + { + if (p) out = ensure(p, 3); + else out = (char*)cJSON_malloc(3); + if (!out) return 0; + strcpy(out, "\"\""); + return out; + } + ptr = str;while ((token = *ptr) && ++len) { if (strchr("\"\\\b\f\n\r\t", token)) len++; else if (token < 32) len += 5;ptr++; } + + if (p) out = ensure(p, len + 3); + else out = (char*)cJSON_malloc(len + 3); + if (!out) return 0; + + ptr2 = out;ptr = str; + *ptr2++ = '\"'; + while (*ptr) + { + if ((unsigned char)*ptr > 31 && *ptr != '\"' && *ptr != '\\') *ptr2++ = *ptr++; + else + { + *ptr2++ = '\\'; + switch (token = *ptr++) + { + case '\\': *ptr2++ = '\\'; break; + case '\"': *ptr2++ = '\"'; break; + case '\b': *ptr2++ = 'b'; break; + case '\f': *ptr2++ = 'f'; break; + case '\n': *ptr2++ = 'n'; break; + case '\r': *ptr2++ = 'r'; break; + case '\t': *ptr2++ = 't'; break; + default: sprintf(ptr2, "u%04x", token);ptr2 += 5; break; /* escape and print */ + } + } + } + *ptr2++ = '\"';*ptr2++ = 0; + return out; +} +/* Invote print_string_ptr (which is useful) on an item. */ +static char* print_string(cJSON* item, printbuffer* p) { return print_string_ptr(item->valuestring, p); } + +/* Predeclare these prototypes. */ +static const char* parse_value(cJSON* item, const char* value); +static char* print_value(cJSON* item, int depth, int fmt, printbuffer* p); +static const char* parse_array(cJSON* item, const char* value); +static char* print_array(cJSON* item, int depth, int fmt, printbuffer* p); +static const char* parse_object(cJSON* item, const char* value); +static char* print_object(cJSON* item, int depth, int fmt, printbuffer* p); + +/* Utility to jump whitespace and cr/lf */ +static const char* skip(const char* in) { while (in && *in && (unsigned char)*in <= 32) in++; return in; } + +/* Parse an object - create a new root, and populate. */ +cJSON* cJSON_ParseWithOpts(const char* value, const char** return_parse_end, int require_null_terminated) +{ + const char* end = 0; + cJSON* c = cJSON_New_Item(); + ep = 0; + if (!c) return 0; /* memory fail */ + + end = parse_value(c, skip(value)); + if (!end) { cJSON_Delete(c);return 0; } /* parse failure. ep is set. */ + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) { end = skip(end);if (*end) { cJSON_Delete(c);ep = end;return 0; } } + if (return_parse_end) *return_parse_end = end; + return c; +} +/* Default options for cJSON_Parse */ +cJSON* cJSON_Parse(const char* value) { return cJSON_ParseWithOpts(value, 0, 0); } + +/* Render a cJSON item/entity/structure to text. */ +char* cJSON_Print(cJSON* item) { return print_value(item, 0, 1, 0); } +char* cJSON_PrintUnformatted(cJSON* item) { return print_value(item, 0, 0, 0); } + +char* cJSON_PrintBuffered(cJSON* item, int prebuffer, int fmt) +{ + printbuffer p; + p.buffer = (char*)cJSON_malloc(prebuffer); + p.length = prebuffer; + p.offset = 0; + return print_value(item, 0, fmt, &p); + return p.buffer; +} + + +/* Parser core - when encountering text, process appropriately. */ +static const char* parse_value(cJSON* item, const char* value) +{ + if (!value) return 0; /* Fail on null. */ + if (!strncmp(value, "null", 4)) { item->type = cJSON_NULL; return value + 4; } + if (!strncmp(value, "false", 5)) { item->type = cJSON_False; return value + 5; } + if (!strncmp(value, "true", 4)) { item->type = cJSON_True; item->valueint = 1; return value + 4; } + if (*value == '\"') { return parse_string(item, value); } + if (*value == '-' || (*value >= '0' && *value <= '9')) { return parse_number(item, value); } + if (*value == '[') { return parse_array(item, value); } + if (*value == '{') { return parse_object(item, value); } + + ep = value;return 0; /* failure. */ +} + +/* Render a value to text. */ +static char* print_value(cJSON* item, int depth, int fmt, printbuffer* p) +{ + char* out = 0; + if (!item) return 0; + if (p) + { + switch ((item->type) & 255) + { + case cJSON_NULL: {out = ensure(p, 5); if (out) strcpy(out, "null"); break;} + case cJSON_False: {out = ensure(p, 6); if (out) strcpy(out, "false"); break;} + case cJSON_True: {out = ensure(p, 5); if (out) strcpy(out, "true"); break;} + case cJSON_Number: out = print_number(item, p);break; + case cJSON_String: out = print_string(item, p);break; + case cJSON_Array: out = print_array(item, depth, fmt, p);break; + case cJSON_Object: out = print_object(item, depth, fmt, p);break; + } + } + else + { + switch ((item->type) & 255) + { + case cJSON_NULL: out = cJSON_strdup("null"); break; + case cJSON_False: out = cJSON_strdup("false");break; + case cJSON_True: out = cJSON_strdup("true"); break; + case cJSON_Number: out = print_number(item, 0);break; + case cJSON_String: out = print_string(item, 0);break; + case cJSON_Array: out = print_array(item, depth, fmt, 0);break; + case cJSON_Object: out = print_object(item, depth, fmt, 0);break; + } + } + return out; +} + +/* Build an array from input text. */ +static const char* parse_array(cJSON* item, const char* value) +{ + cJSON* child; + if (*value != '[') { ep = value;return 0; } /* not an array! */ + + item->type = cJSON_Array; + value = skip(value + 1); + if (*value == ']') return value + 1; /* empty array. */ + + item->child = child = cJSON_New_Item(); + if (!item->child) return 0; /* memory fail */ + value = skip(parse_value(child, skip(value))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value == ',') + { + cJSON* new_item; + if (!(new_item = cJSON_New_Item())) return 0; /* memory fail */ + child->next = new_item;new_item->prev = child;child = new_item; + value = skip(parse_value(child, skip(value + 1))); + if (!value) return 0; /* memory fail */ + } + + if (*value == ']') return value + 1; /* end of array */ + ep = value;return 0; /* malformed. */ +} + +/* Render an array to text */ +static char* print_array(cJSON* item, int depth, int fmt, printbuffer* p) +{ + char** entries; + char* out = 0, * ptr, * ret;int len = 5; + cJSON* child = item->child; + int numentries = 0, i = 0, fail = 0; + size_t tmplen = 0; + + /* How many entries in the array? */ + while (child) numentries++, child = child->next; + /* Explicitly handle numentries==0 */ + if (!numentries) + { + if (p) out = ensure(p, 3); + else out = (char*)cJSON_malloc(3); + if (out) strcpy(out, "[]"); + return out; + } + + if (p) + { + /* Compose the output array. */ + i = p->offset; + ptr = ensure(p, 1);if (!ptr) return 0; *ptr = '['; p->offset++; + child = item->child; + while (child && !fail) + { + print_value(child, depth + 1, fmt, p); + p->offset = update(p); + if (child->next) { len = fmt ? 2 : 1;ptr = ensure(p, len + 1);if (!ptr) return 0;*ptr++ = ',';if (fmt)*ptr++ = ' ';*ptr = 0;p->offset += len; } + child = child->next; + } + ptr = ensure(p, 2);if (!ptr) return 0; *ptr++ = ']';*ptr = 0; + out = (p->buffer) + i; + } + else + { + /* Allocate an array to hold the values for each */ + entries = (char**)cJSON_malloc(numentries * sizeof(char*)); + if (!entries) return 0; + memset(entries, 0, numentries * sizeof(char*)); + /* Retrieve all the results: */ + child = item->child; + while (child && !fail) + { + ret = print_value(child, depth + 1, fmt, 0); + entries[i++] = ret; + if (ret) len += strlen(ret) + 2 + (fmt ? 1 : 0); else fail = 1; + child = child->next; + } + + /* If we didn't fail, try to malloc the output string */ + if (!fail) out = (char*)cJSON_malloc(len); + /* If that fails, we fail. */ + if (!out) fail = 1; + + /* Handle failure. */ + if (fail) + { + for (i = 0;i < numentries;i++) if (entries[i]) cJSON_free(entries[i]); + cJSON_free(entries); + return 0; + } + + /* Compose the output array. */ + *out = '['; + ptr = out + 1;*ptr = 0; + for (i = 0;i < numentries;i++) + { + tmplen = strlen(entries[i]);memcpy(ptr, entries[i], tmplen);ptr += tmplen; + if (i != numentries - 1) { *ptr++ = ',';if (fmt)*ptr++ = ' ';*ptr = 0; } + cJSON_free(entries[i]); + } + cJSON_free(entries); + *ptr++ = ']';*ptr++ = 0; + } + return out; +} + +/* Build an object from the text. */ +static const char* parse_object(cJSON* item, const char* value) +{ + cJSON* child; + if (*value != '{') { ep = value;return 0; } /* not an object! */ + + item->type = cJSON_Object; + value = skip(value + 1); + if (*value == '}') return value + 1; /* empty array. */ + + item->child = child = cJSON_New_Item(); + if (!item->child) return 0; + value = skip(parse_string(child, skip(value))); + if (!value) return 0; + child->string = child->valuestring;child->valuestring = 0; + if (*value != ':') { ep = value;return 0; } /* fail! */ + value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */ + if (!value) return 0; + + while (*value == ',') + { + cJSON* new_item; + if (!(new_item = cJSON_New_Item())) return 0; /* memory fail */ + child->next = new_item;new_item->prev = child;child = new_item; + value = skip(parse_string(child, skip(value + 1))); + if (!value) return 0; + child->string = child->valuestring;child->valuestring = 0; + if (*value != ':') { ep = value;return 0; } /* fail! */ + value = skip(parse_value(child, skip(value + 1))); /* skip any spacing, get the value. */ + if (!value) return 0; + } + + if (*value == '}') return value + 1; /* end of array */ + ep = value;return 0; /* malformed. */ +} + +/* Render an object to text. */ +static char* print_object(cJSON* item, int depth, int fmt, printbuffer* p) +{ + char** entries = 0, ** names = 0; + char* out = 0, * ptr, * ret, * str;int len = 7, i = 0, j; + cJSON* child = item->child; + int numentries = 0, fail = 0; + size_t tmplen = 0; + /* Count the number of entries. */ + while (child) numentries++, child = child->next; + /* Explicitly handle empty object case */ + if (!numentries) + { + if (p) out = ensure(p, fmt ? depth + 4 : 3); + else out = (char*)cJSON_malloc(fmt ? depth + 4 : 3); + if (!out) return 0; + ptr = out;*ptr++ = '{'; + if (fmt) { *ptr++ = '\n';for (i = 0;i < depth - 1;i++) *ptr++ = '\t'; } + *ptr++ = '}';*ptr++ = 0; + return out; + } + if (p) + { + /* Compose the output: */ + i = p->offset; + len = fmt ? 2 : 1; ptr = ensure(p, len + 1); if (!ptr) return 0; + *ptr++ = '{'; if (fmt) *ptr++ = '\n'; *ptr = 0; p->offset += len; + child = item->child;depth++; + while (child) + { + if (fmt) + { + ptr = ensure(p, depth); if (!ptr) return 0; + for (j = 0;j < depth;j++) *ptr++ = '\t'; + p->offset += depth; + } + print_string_ptr(child->string, p); + p->offset = update(p); + + len = fmt ? 2 : 1; + ptr = ensure(p, len); if (!ptr) return 0; + *ptr++ = ':';if (fmt) *ptr++ = '\t'; + p->offset += len; + + print_value(child, depth, fmt, p); + p->offset = update(p); + + len = (fmt ? 1 : 0) + (child->next ? 1 : 0); + ptr = ensure(p, len + 1); if (!ptr) return 0; + if (child->next) *ptr++ = ','; + if (fmt) *ptr++ = '\n';*ptr = 0; + p->offset += len; + child = child->next; + } + ptr = ensure(p, fmt ? (depth + 1) : 2); if (!ptr) return 0; + if (fmt) for (i = 0;i < depth - 1;i++) *ptr++ = '\t'; + *ptr++ = '}';*ptr = 0; + out = (p->buffer) + i; + } + else + { + /* Allocate space for the names and the objects */ + entries = (char**)cJSON_malloc(numentries * sizeof(char*)); + if (!entries) return 0; + names = (char**)cJSON_malloc(numentries * sizeof(char*)); + if (!names) { cJSON_free(entries);return 0; } + memset(entries, 0, sizeof(char*) * numentries); + memset(names, 0, sizeof(char*) * numentries); + + /* Collect all the results into our arrays: */ + child = item->child;depth++;if (fmt) len += depth; + while (child) + { + names[i] = str = print_string_ptr(child->string, 0); + entries[i++] = ret = print_value(child, depth, fmt, 0); + if (str && ret) len += strlen(ret) + strlen(str) + 2 + (fmt ? 2 + depth : 0); else fail = 1; + child = child->next; + } + + /* Try to allocate the output string */ + if (!fail) out = (char*)cJSON_malloc(len); + if (!out) fail = 1; + + /* Handle failure */ + if (fail) + { + for (i = 0;i < numentries;i++) { if (names[i]) cJSON_free(names[i]);if (entries[i]) cJSON_free(entries[i]); } + cJSON_free(names);cJSON_free(entries); + return 0; + } + + /* Compose the output: */ + *out = '{';ptr = out + 1;if (fmt)*ptr++ = '\n';*ptr = 0; + for (i = 0;i < numentries;i++) + { + if (fmt) for (j = 0;j < depth;j++) *ptr++ = '\t'; + tmplen = strlen(names[i]);memcpy(ptr, names[i], tmplen);ptr += tmplen; + *ptr++ = ':';if (fmt) *ptr++ = '\t'; + strcpy(ptr, entries[i]);ptr += strlen(entries[i]); + if (i != numentries - 1) *ptr++ = ','; + if (fmt) *ptr++ = '\n';*ptr = 0; + cJSON_free(names[i]);cJSON_free(entries[i]); + } + + cJSON_free(names);cJSON_free(entries); + if (fmt) for (i = 0;i < depth - 1;i++) *ptr++ = '\t'; + *ptr++ = '}';*ptr++ = 0; + } + return out; +} + +/* Get Array size/item / object item. */ +int cJSON_GetArraySize(cJSON* array) { cJSON* c = array->child;int i = 0;while (c)i++, c = c->next;return i; } +cJSON* cJSON_GetArrayItem(cJSON* array, int item) { cJSON* c = array->child; while (c && item > 0) item--, c = c->next; return c; } +cJSON* cJSON_GetObjectItem(cJSON* object, const char* string) { cJSON* c = object->child; while (c && cJSON_strcasecmp(c->string, string)) c = c->next; return c; } + +/* Utility for array list handling. */ +static void suffix_object(cJSON* prev, cJSON* item) { prev->next = item;item->prev = prev; } +/* Utility for handling references. */ +static cJSON* create_reference(cJSON* item) { cJSON* ref = cJSON_New_Item();if (!ref) return 0;memcpy(ref, item, sizeof(cJSON));ref->string = 0;ref->type |= cJSON_IsReference;ref->next = ref->prev = 0;return ref; } + +/* Add item to array/object. */ +void cJSON_AddItemToArray(cJSON* array, cJSON* item) { cJSON* c = array->child;if (!item) return; if (!c) { array->child = item; } else { while (c && c->next) c = c->next; suffix_object(c, item); } } +void cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item) { if (!item) return; if (item->string) cJSON_free(item->string);item->string = cJSON_strdup(string);cJSON_AddItemToArray(object, item); } +void cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item) { if (!item) return; if (!(item->type & cJSON_StringIsConst) && item->string) cJSON_free(item->string);item->string = (char*)string;item->type |= cJSON_StringIsConst;cJSON_AddItemToArray(object, item); } +void cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item) { cJSON_AddItemToArray(array, create_reference(item)); } +void cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item) { cJSON_AddItemToObject(object, string, create_reference(item)); } + +cJSON* cJSON_DetachItemFromArray(cJSON* array, int which) { + cJSON* c = array->child;while (c && which > 0) c = c->next, which--;if (!c) return 0; + if (c->prev) c->prev->next = c->next;if (c->next) c->next->prev = c->prev;if (c == array->child) array->child = c->next;c->prev = c->next = 0;return c; +} +void cJSON_DeleteItemFromArray(cJSON* array, int which) { cJSON_Delete(cJSON_DetachItemFromArray(array, which)); } +cJSON* cJSON_DetachItemFromObject(cJSON* object, const char* string) { int i = 0;cJSON* c = object->child;while (c && cJSON_strcasecmp(c->string, string)) i++, c = c->next;if (c) return cJSON_DetachItemFromArray(object, i);return 0; } +void cJSON_DeleteItemFromObject(cJSON* object, const char* string) { cJSON_Delete(cJSON_DetachItemFromObject(object, string)); } + +/* Replace array/object items with new ones. */ +void cJSON_InsertItemInArray(cJSON* array, int which, cJSON* newitem) { + cJSON* c = array->child;while (c && which > 0) c = c->next, which--;if (!c) { cJSON_AddItemToArray(array, newitem);return; } + newitem->next = c;newitem->prev = c->prev;c->prev = newitem;if (c == array->child) array->child = newitem; else newitem->prev->next = newitem; +} +void cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem) { + cJSON* c = array->child;while (c && which > 0) c = c->next, which--;if (!c) return; + newitem->next = c->next;newitem->prev = c->prev;if (newitem->next) newitem->next->prev = newitem; + if (c == array->child) array->child = newitem; else newitem->prev->next = newitem;c->next = c->prev = 0;cJSON_Delete(c); +} +void cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem) { int i = 0;cJSON* c = object->child;while (c && cJSON_strcasecmp(c->string, string))i++, c = c->next;if (c) { newitem->string = cJSON_strdup(string);cJSON_ReplaceItemInArray(object, i, newitem); } } + +/* Create basic types: */ +cJSON* cJSON_CreateNull(void) { cJSON* item = cJSON_New_Item();if (item)item->type = cJSON_NULL;return item; } +cJSON* cJSON_CreateTrue(void) { cJSON* item = cJSON_New_Item();if (item)item->type = cJSON_True;return item; } +cJSON* cJSON_CreateFalse(void) { cJSON* item = cJSON_New_Item();if (item)item->type = cJSON_False;return item; } +cJSON* cJSON_CreateBool(int b) { cJSON* item = cJSON_New_Item();if (item)item->type = b ? cJSON_True : cJSON_False;return item; } +cJSON* cJSON_CreateNumber(double num) { cJSON* item = cJSON_New_Item();if (item) { item->type = cJSON_Number;item->valuedouble = num;item->valueint = (int)num; }return item; } +cJSON* cJSON_CreateString(const char* string) { cJSON* item = cJSON_New_Item();if (item) { item->type = cJSON_String;item->valuestring = cJSON_strdup(string); }return item; } +cJSON* cJSON_CreateArray(void) { cJSON* item = cJSON_New_Item();if (item)item->type = cJSON_Array;return item; } +cJSON* cJSON_CreateObject(void) { cJSON* item = cJSON_New_Item();if (item)item->type = cJSON_Object;return item; } + +/* Create Arrays: */ +cJSON* cJSON_CreateIntArray(const int* numbers, int count) { int i;cJSON* n = 0, * p = 0, * a = cJSON_CreateArray();for (i = 0;a && i < count;i++) { n = cJSON_CreateNumber(numbers[i]);if (!i)a->child = n;else suffix_object(p, n);p = n; }return a; } +cJSON* cJSON_CreateFloatArray(const float* numbers, int count) { int i;cJSON* n = 0, * p = 0, * a = cJSON_CreateArray();for (i = 0;a && i < count;i++) { n = cJSON_CreateNumber(numbers[i]);if (!i)a->child = n;else suffix_object(p, n);p = n; }return a; } +cJSON* cJSON_CreateDoubleArray(const double* numbers, int count) { int i;cJSON* n = 0, * p = 0, * a = cJSON_CreateArray();for (i = 0;a && i < count;i++) { n = cJSON_CreateNumber(numbers[i]);if (!i)a->child = n;else suffix_object(p, n);p = n; }return a; } +cJSON* cJSON_CreateStringArray(const char** strings, int count) { int i;cJSON* n = 0, * p = 0, * a = cJSON_CreateArray();for (i = 0;a && i < count;i++) { n = cJSON_CreateString(strings[i]);if (!i)a->child = n;else suffix_object(p, n);p = n; }return a; } + +/* Duplication */ +cJSON* cJSON_Duplicate(cJSON* item, int recurse) +{ + cJSON* newitem, * cptr, * nptr = 0, * newchild; + /* Bail on bad ptr */ + if (!item) return 0; + /* Create new item */ + newitem = cJSON_New_Item(); + if (!newitem) return 0; + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference), newitem->valueint = item->valueint, newitem->valuedouble = item->valuedouble; + if (item->valuestring) { newitem->valuestring = cJSON_strdup(item->valuestring); if (!newitem->valuestring) { cJSON_Delete(newitem);return 0; } } + if (item->string) { newitem->string = cJSON_strdup(item->string); if (!newitem->string) { cJSON_Delete(newitem);return 0; } } + /* If non-recursive, then we're done! */ + if (!recurse) return newitem; + /* Walk the ->next chain for the child. */ + cptr = item->child; + while (cptr) + { + newchild = cJSON_Duplicate(cptr, 1); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) { cJSON_Delete(newitem);return 0; } + if (nptr) { nptr->next = newchild, newchild->prev = nptr;nptr = newchild; } /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + else { newitem->child = newchild;nptr = newchild; } /* Set newitem->child and move to it */ + cptr = cptr->next; + } + return newitem; +} + +void cJSON_Minify(char* json) +{ + char* into = json; + while (*json) + { + if (*json == ' ') json++; + else if (*json == '\t') json++; /* Whitespace characters. */ + else if (*json == '\r') json++; + else if (*json == '\n') json++; + else if (*json == '/' && json[1] == '/') while (*json && *json != '\n') json++; /* double-slash comments, to end of line. */ + else if (*json == '/' && json[1] == '*') { while (*json && !(*json == '*' && json[1] == '/')) json++;json += 2; } /* multiline comments. */ + else if (*json == '\"') { *into++ = *json++;while (*json && *json != '\"') { if (*json == '\\') *into++ = *json++;*into++ = *json++; }*into++ = *json++; } /* string literals, which are \" sensitive. */ + else *into++ = *json++; /* All other characters. */ + } + *into = 0; /* and null-terminate. */ +} diff --git a/FTMM_PLM_TO_SAPAPI/cJSON.h b/FTMM_PLM_TO_SAPAPI/cJSON.h new file mode 100644 index 0000000..84f0fc8 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/cJSON.h @@ -0,0 +1,149 @@ +/* + Copyright (c) 2009 Dave Gamble + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + + /* cJSON Types: */ +#define cJSON_False 0 +#define cJSON_True 1 +#define cJSON_NULL 2 +#define cJSON_Number 3 +#define cJSON_String 4 +#define cJSON_Array 5 +#define cJSON_Object 6 + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ + typedef struct cJSON { + struct cJSON* next, * prev; /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON* child; /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + + int type; /* The type of the item, as above. */ + + char* valuestring; /* The item's string, if type==cJSON_String */ + int valueint; /* The item's number, if type==cJSON_Number */ + double valuedouble; /* The item's number, if type==cJSON_Number */ + + char* string; /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + } cJSON; + + typedef struct cJSON_Hooks { + void* (*malloc_fn)(size_t sz); + void (*free_fn)(void* ptr); + } cJSON_Hooks; + + /* Supply malloc, realloc and free functions to cJSON */ + extern void cJSON_InitHooks(cJSON_Hooks* hooks); + + + /* Supply a block of JSON, and this returns a cJSON object you can interrogate. Call cJSON_Delete when finished. */ + extern cJSON* cJSON_Parse(const char* value); + /* Render a cJSON entity to text for transfer/storage. Free the char* when finished. */ + extern char* cJSON_Print(cJSON* item); + /* Render a cJSON entity to text for transfer/storage without any formatting. Free the char* when finished. */ + extern char* cJSON_PrintUnformatted(cJSON* item); + /* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ + extern char* cJSON_PrintBuffered(cJSON* item, int prebuffer, int fmt); + /* Delete a cJSON entity and all subentities. */ + extern void cJSON_Delete(cJSON* c); + + /* Returns the number of items in an array (or object). */ + extern int cJSON_GetArraySize(cJSON* array); + /* Retrieve item number "item" from array "array". Returns NULL if unsuccessful. */ + extern cJSON* cJSON_GetArrayItem(cJSON* array, int item); + /* Get item "string" from object. Case insensitive. */ + extern cJSON* cJSON_GetObjectItem(cJSON* object, const char* string); + + /* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ + extern const char* cJSON_GetErrorPtr(void); + + /* These calls create a cJSON item of the appropriate type. */ + extern cJSON* cJSON_CreateNull(void); + extern cJSON* cJSON_CreateTrue(void); + extern cJSON* cJSON_CreateFalse(void); + extern cJSON* cJSON_CreateBool(int b); + extern cJSON* cJSON_CreateNumber(double num); + extern cJSON* cJSON_CreateString(const char* string); + extern cJSON* cJSON_CreateArray(void); + extern cJSON* cJSON_CreateObject(void); + + /* These utilities create an Array of count items. */ + extern cJSON* cJSON_CreateIntArray(const int* numbers, int count); + extern cJSON* cJSON_CreateFloatArray(const float* numbers, int count); + extern cJSON* cJSON_CreateDoubleArray(const double* numbers, int count); + extern cJSON* cJSON_CreateStringArray(const char** strings, int count); + + /* Append item to the specified array/object. */ + extern void cJSON_AddItemToArray(cJSON* array, cJSON* item); + extern void cJSON_AddItemToObject(cJSON* object, const char* string, cJSON* item); + extern void cJSON_AddItemToObjectCS(cJSON* object, const char* string, cJSON* item); /* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object */ + /* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ + extern void cJSON_AddItemReferenceToArray(cJSON* array, cJSON* item); + extern void cJSON_AddItemReferenceToObject(cJSON* object, const char* string, cJSON* item); + + /* Remove/Detatch items from Arrays/Objects. */ + extern cJSON* cJSON_DetachItemFromArray(cJSON* array, int which); + extern void cJSON_DeleteItemFromArray(cJSON* array, int which); + extern cJSON* cJSON_DetachItemFromObject(cJSON* object, const char* string); + extern void cJSON_DeleteItemFromObject(cJSON* object, const char* string); + + /* Update array items. */ + extern void cJSON_InsertItemInArray(cJSON* array, int which, cJSON* newitem); /* Shifts pre-existing items to the right. */ + extern void cJSON_ReplaceItemInArray(cJSON* array, int which, cJSON* newitem); + extern void cJSON_ReplaceItemInObject(cJSON* object, const char* string, cJSON* newitem); + + /* Duplicate a cJSON item */ + extern cJSON* cJSON_Duplicate(cJSON* item, int recurse); + /* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + need to be released. With recurse!=0, it will duplicate any children connected to the item. + The item->next and ->prev pointers are always zero on return from Duplicate. */ + + /* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ + extern cJSON* cJSON_ParseWithOpts(const char* value, const char** return_parse_end, int require_null_terminated); + + extern void cJSON_Minify(char* json); + + /* Macros for creating things quickly. */ +#define cJSON_AddNullToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateNull()) +#define cJSON_AddTrueToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateTrue()) +#define cJSON_AddFalseToObject(object,name) cJSON_AddItemToObject(object, name, cJSON_CreateFalse()) +#define cJSON_AddBoolToObject(object,name,b) cJSON_AddItemToObject(object, name, cJSON_CreateBool(b)) +#define cJSON_AddNumberToObject(object,name,n) cJSON_AddItemToObject(object, name, cJSON_CreateNumber(n)) +#define cJSON_AddStringToObject(object,name,s) cJSON_AddItemToObject(object, name, cJSON_CreateString(s)) + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) +#define cJSON_SetNumberValue(object,val) ((object)?(object)->valueint=(object)->valuedouble=(val):(val)) + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/FTMM_PLM_TO_SAPAPI/connor_itk_util.cpp b/FTMM_PLM_TO_SAPAPI/connor_itk_util.cpp new file mode 100644 index 0000000..31978d7 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/connor_itk_util.cpp @@ -0,0 +1,628 @@ +#pragma warning(disable: 4996) +#include +#include +#ifdef WIN32 +#include +#include +#else +#include +#endif +#include "connor_itk_util.h" +extern "C" int POM_AM__set_application_bypass(logical bypass); + +#define ARGS_LENGTH 200 +#define ARGS_NAME_DEBUG "-debug" +#define DEBUG "-debug=" +#define MAX_PRINTLINE_LENGTH 10000 +#define MAX_PATH_LENGTH 2000 +#define MAX_ARGUMENT_LENGTH 400 +#define MAX_FILE_EXT_LENGTH 10 +#define TRUE_FLAG 1 +#define FALSE_FLAG 0 +#define DETAILLOG 1 + +void ECHO(char* format, ...) +{ + //if( !YFJC_OPT_DEBUG ) + // return; + + char msg[4096]; + va_list args; + + va_start(args, format); + vsprintf(msg, format, args); + va_end(args); + + printf(msg); + TC_write_syslog(msg); +} + +FILE* logFile = NULL; + +/*=============================================================================* + * FUNCTION: current_time + * PURPOSE : get the current datetime + * INPUT: + * date_t* date_tag // current date time tag + * + * RETURN: + * void + *============================================================================*/ +void current_time(date_t* date_tag) +{ + time_t ltime; + struct tm* today; + + // Set time zone from TZ environment variable. If TZ is not set, + // the operating system is queried to obtain the default value + // for the variable. + // + //_tzset(); + + // Get UNIX-style time and display as number and string. + time(<ime); + + today = localtime(<ime); + date_tag->year = today->tm_year + 1900; + date_tag->month = today->tm_mon; + date_tag->day = today->tm_mday; + date_tag->hour = today->tm_hour; + date_tag->minute = today->tm_min; + date_tag->second = today->tm_sec; +} +/*=============================================================================* + * FUNCTION: CreateLogFile + * PURPOSE : create log file + * INPUT: + * char* FunctionName // the funtion which need to create log file + * FILE** logFile // out: the log file pointer + * + * RETURN: + * void + *============================================================================*/ +void CreateLogFile(char* FunctionName, char** fullname) +{ + int i = 0, ifail = ITK_ok; + //date_t status_now; + //char* date_string = NULL; + char date_string[MAX_PATH_LENGTH]; + char logFileDir[MAX_PATH_LENGTH]; + char logFileName[MAX_PATH_LENGTH]; + + char* session_uid = NULL; + tag_t session_tag = NULLTAG; + time_t now; + struct tm* p; + + time(&now); + + logFile = NULL; + //current_time(&status_now); + p = localtime(&now); + + memset(date_string, 0, sizeof(date_string)); + //sprintf(date_string,"%4d%02d%02d%02d%02d%02d",1900+p->tm_year,p->tm_mon+1 ,p->tm_mday ,p->tm_hour,p->tm_min ,p->tm_sec ); + sprintf(date_string, "%4d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday); + //if( DATE_date_to_string( status_now, "%Y%m%d%H%M%S", &date_string) != ITK_ok ) + //ifail = ITK_date_to_string (status_now, &date_string ); + //if (ifail) + //{ + // printf("!*ERROR*!: Failed to get current date time\n"); + // goto CLEANUP; + //} + + memset(logFileDir, 0, sizeof(logFileDir)); + memset(logFileName, 0, sizeof(logFileName)); + //get log dir + //sprintf(logFileDir, "%s", getenv("TEMP")); + sprintf(logFileDir, "%s", "C:\\Siemens\\InterfaceLog"); + printf("\n log file dir: %s\n", logFileDir); + //try to change dir to TC_USER_LOG_DIR + if (chdir(logFileDir) != ITK_ok) + { + //not set TC_USER_LOG_DIR + //log in to default TC_LOG + memset(logFileDir, 0, sizeof(logFileDir)); + sprintf(logFileDir, "%s", getenv("TC_LOG")); + printf("\n TC_USER_LOG_DIR invalide, log file dir: %s\n", logFileDir); + if (chdir(logFileDir) != ITK_ok) + { + //still can not change to log dir + printf("!*ERROR*!: Failed to change dir to TC_USER_LOG_DIR\n"); + goto CLEANUP; + } + } + + //get session_uid to make sure the log file name unique + POM_ask_session(&session_tag); + ITK__convert_tag_to_uid(session_tag, &session_uid); + + + //get logFileName + //sprintf(logFileName, "%s_%s_%s.log", FunctionName, session_uid, date_string); + sprintf(logFileName, "%s_%s.log", FunctionName, date_string); + printf("log file name: %s\n", logFileName); + + *fullname = (char*)MEM_alloc(sizeof(char) * 512); + sprintf(*fullname, "%s\\%s", logFileDir, logFileName); + + //for(i = 0; _access((char *)logFileName, 4) == 0; i++) + /*{ + memset(logFileName, 0, sizeof(logFileName)); + sprintf(logFileName, "%s_%s_%s_%d.log", FunctionName, session_uid, date_string, i); + } + printf("final log file name: %s\n", logFileName);*/ + + //create log file + logFile = fopen(logFileName, "a"); + +CLEANUP: + //DOFREE(date_string); + DOFREE(session_uid); +} + +void CreateLogFile2(char* FunctionName, char** fullname, char* fileDir) +{ + int i = 0, ifail = ITK_ok; + //date_t status_now; + //char* date_string = NULL; + char date_string[MAX_PATH_LENGTH]; + char logFileDir[MAX_PATH_LENGTH]; + + char logFileName[MAX_PATH_LENGTH]; + + char* session_uid = NULL; + tag_t session_tag = NULLTAG; + time_t now; + struct tm* p; + + time(&now); + + logFile = NULL; + //current_time(&status_now); + p = localtime(&now); + + memset(date_string, 0, sizeof(date_string)); + //sprintf(date_string,"%4d%02d%02d%02d%02d%02d",1900+p->tm_year,p->tm_mon+1 ,p->tm_mday ,p->tm_hour,p->tm_min ,p->tm_sec ); + sprintf(date_string, "%4d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday); + //if( DATE_date_to_string( status_now, "%Y%m%d%H%M%S", &date_string) != ITK_ok ) + //ifail = ITK_date_to_string (status_now, &date_string ); + //if (ifail) + //{ + // printf("!*ERROR*!: Failed to get current date time\n"); + // goto CLEANUP; + //} + + memset(logFileDir, 0, sizeof(logFileDir)); + memset(logFileName, 0, sizeof(logFileName)); + ////get log dir + //sprintf(logFileDir, "%s", getenv("TEMP")); + strcat(logFileDir, fileDir); + printf("\n log file dir: %s\n", logFileDir); + //try to change dir to TC_USER_LOG_DIR + if (chdir(logFileDir) != ITK_ok) + { + //not set TC_USER_LOG_DIR + //log in to default TC_LOG + memset(logFileDir, 0, sizeof(logFileDir)); + sprintf(logFileDir, "%s", getenv("TC_LOG")); + printf("\n TC_USER_LOG_DIR invalide, log file dir: %s\n", logFileDir); + if (chdir(logFileDir) != ITK_ok) + { + //still can not change to log dir + printf("!*ERROR*!: Failed to change dir to TC_USER_LOG_DIR\n"); + goto CLEANUP; + } + } + + //get session_uid to make sure the log file name unique + POM_ask_session(&session_tag); + ITK__convert_tag_to_uid(session_tag, &session_uid); + + + //get logFileName + //sprintf(logFileName, "%s_%s_%s.log", FunctionName, session_uid, date_string); + sprintf(logFileName, "%s_%s.log", FunctionName, date_string); + printf("log file name: %s\n", logFileName); + + *fullname = (char*)MEM_alloc(sizeof(char) * 512); + sprintf(*fullname, "%s\\%s", logFileDir, logFileName); + + //for(i = 0; _access((char *)logFileName, 4) == 0; i++) + /*{ + memset(logFileName, 0, sizeof(logFileName)); + sprintf(logFileName, "%s_%s_%s_%d.log", FunctionName, session_uid, date_string, i); + } + printf("final log file name: %s\n", logFileName);*/ + + //create log file + logFile = fopen(logFileName, "a"); + +CLEANUP: + //DOFREE(date_string); + DOFREE(session_uid); +} + +/*=============================================================================* + * FUNCTION: WriteLog + * PURPOSE : write log, if debug log File not null, write log message to log File + * INPUT: + * const char* format // debug message string + * + * RETURN: + * void + *============================================================================*/ +//void WriteLog(const char* format, ...) +//{ +// va_list arg; +// char tmp[MAX_PRINTLINE_LENGTH]; +// if (logFile) +// { +// //get the message +// memset(tmp, 0, sizeof(tmp)); +// va_start(arg, format); +// vsprintf(tmp, format, arg); +// va_end(arg); +// +// //----------print to command window for trace--------// +// printf("%s\n", tmp); +// +// //print message to log file +// fprintf(logFile, "%s\n", tmp); +// fflush(logFile); +// } +// else +// { +// printf("*!Error!*: Log File Not Exist\n"); +// } +//} +void WriteLog(const char* format, ...) { + va_list arg; + if (logFile) { + va_start(arg, format); + + va_list arg_copy; + va_copy(arg_copy, arg); // һݿɱбԽдС + + // ȡʽַĴС + int size = vsnprintf(nullptr, 0, format, arg_copy) + 1; // ȡַȲֹ '\0' + va_end(arg_copy); + + // ̬ڴ + char* tmp = new char[size]; + vsnprintf(tmp, size, format, arg); // ʽд뵽ַ̬ + va_end(arg); + + // д + printf("%s\n", tmp); + + // ־ļ + fprintf(logFile, "%s\n", tmp); + fflush(logFile); + + // ͷڴ + delete[] tmp; + } + else { + printf("*!Error!*: Log File Not Exist\n"); + } +} + + +void WriteLog2(string value) { + if (logFile) + { + fprintf(logFile, "%s\n", value.c_str()); + fflush(logFile); + } + else + { + printf("*!Error!*: Log File Not Exist\n"); + } +} +void CloseLog(void) +{ + if (logFile) + { + fclose(logFile); + logFile = NULL; + } +} + + +string getUUid() +{ + GUID guid; + char buffer[64] = { 0 }; + if (CoCreateGuid(&guid)) + { + printf("create guid error\n"); + return ""; + } + //_snprintf(buffer, sizeof(buffer), "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X", guid.Data1, guid.Data2, guid.Data3, + // guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + sprintf_s(buffer, sizeof(buffer), + "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x", + guid.Data1, guid.Data2, guid.Data3, + guid.Data4[0], guid.Data4[1], guid.Data4[2], guid.Data4[3], + guid.Data4[4], guid.Data4[5], guid.Data4[6], guid.Data4[7]); + + return buffer; +} + +char* GbkToUtf8(const char* src_str) +{ + int len = MultiByteToWideChar(CP_ACP, 0, src_str, -1, NULL, 0); + wchar_t* wstr = (wchar_t*)MEM_alloc((len + 1) * sizeof(wchar_t)); + memset(wstr, 0, len + 1); + MultiByteToWideChar(CP_ACP, 0, src_str, -1, wstr, len); + len = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL); + char* str = (char*)MEM_alloc((len + 1) * sizeof(char)); + + memset(str, 0, len + 1); + WideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL); + return str; +} + +char* Utf8ToGbk(const char* src_str) +{ + int len = MultiByteToWideChar(CP_UTF8, 0, src_str, -1, NULL, 0); + wchar_t* wszGBK = (wchar_t*)MEM_alloc((len + 1) * sizeof(wchar_t)); + memset(wszGBK, 0, len * 2 + 2); + MultiByteToWideChar(CP_UTF8, 0, src_str, -1, wszGBK, len); + len = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL); + char* szGBK = (char*)MEM_alloc((len + 1) * sizeof(char)); + + memset(szGBK, 0, len + 1); + WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL); + return szGBK; +} + +void starTime() { + time_t now; + struct tm* p; + time(&now); + p = localtime(&now); + WriteLog("start time %4d%02d%02d%02d%02d%02d", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); +} + +/** +* +* жijǷΪItemRevision +* +*/ +logical checkIsItemRevision(tag_t objtag) { + tag_t type = NULLTAG; + tag_t item_type = NULLTAG; + logical isItems = false; + ITKCALL(TCTYPE_ask_object_type(objtag, &type)); + ITKCALL(TCTYPE_find_type("ItemRevision", "", &item_type)); + if (item_type != NULLTAG) { + logical isok = FALSE; + ITKCALL(TCTYPE_is_type_of(type, item_type, &isok)); + if (isok) { + isItems = TRUE; + } + else { + isItems = FALSE; + } + } + return isItems; +} + +int checkIsInType(tag_t objtag, string parentType) { + tag_t type = NULLTAG; + tag_t item_type = NULLTAG; + ITKCALL(TCTYPE_ask_object_type(objtag, &type)); + ITKCALL(TCTYPE_find_type(parentType.c_str(), "", &item_type)); + if (item_type != NULLTAG) { + logical isok = FALSE; + ITKCALL(TCTYPE_is_type_of(type, item_type, &isok)); + if (isok) { + return 1; + } + else { + return 0; + } + } + return 0; +} + +int getPrefStrings(const char* preference, vector& pref_vec) +{ + int ifail = ITK_ok, i = 0, j = 0, k = 0, num = 0; + char** values; + ITKCALL(ifail = PREF_ask_char_values(preference, &num, &values)); + for (i = 0; i < num; i++) + { + pref_vec.push_back(values[i]); + } + DOFREE(values); + return ifail; +} + +/******************************************************************* +* +*ǩϢд뵽мļ +* +*@param file_content ǩϢ +*@param item_id id +*@param file_name ļ +* +*******************************************************************/ +int Supor_create_signinfo_file(char* file_content, char* item_id, char** file_name) +{ + time_t now; + struct tm* p; + FILE* filePtr = NULL; + char temp_dir[MAX_PATH_LENGTH]; + char local_path[MAX_PATH] = ""; + char date_string[MAX_PATH_LENGTH]; + memset(temp_dir, 0, sizeof(temp_dir)); + memset(local_path, 0, sizeof(local_path)); + sprintf(temp_dir, "%s", getenv("TEMP")); + printf("\n file dir: %s\n", temp_dir); + time(&now); + p = localtime(&now); + if (chdir(temp_dir) != ITK_ok) + { + memset(temp_dir, 0, sizeof(temp_dir)); + sprintf(temp_dir, "%s", getenv("TC_LOG")); + printf("\n TC_USER_LOG_DIR invalide, log file dir: %s\n", temp_dir); + if (chdir(temp_dir) != ITK_ok) + { + printf("!*ERROR*!: Failed to change dir to TC_USER_LOG_DIR\n"); + + } + } + memset(date_string, 0, sizeof(date_string)); + if (item_id != NULL) { + sprintf(date_string, "%s_%4d%02d%02d%02d%02d%02d.dat", item_id, 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + } + else + { + sprintf(date_string, "%4d%02d%02d%02d%02d%02d.dat", 1900 + p->tm_year, p->tm_mon + 1, p->tm_mday, p->tm_hour, p->tm_min, p->tm_sec); + } + printf("file name: %s\n", date_string); + filePtr = fopen(date_string, "w"); + printf("create the temp dat file success!\n"); + *file_name = (char*)MEM_alloc(sizeof(char) * 512); + sprintf(local_path, "%s\\%s", temp_dir, date_string); + strcpy((*file_name), local_path); + fprintf(filePtr, "%s", file_content); + //fwrite(file_content, sizeof(char), strlen(file_content), filePtr); + fclose(filePtr); + + return ITK_ok; +} +int Connor_set_bypass(void* returnValue) +{ + POM_AM__set_application_bypass(true); + return 0; +} + +int Connor_close_bypass(void* returnValue) +{ + POM_AM__set_application_bypass(false); + return 0; +} + +int MT_add_release_status(void* return_data) { + int ifail = ITK_ok; + tag_t tags = NULLTAG; + char* client_string2 = NULL; + ITKCALL(ifail = USERARG_get_tag_argument(&tags)); + ITKCALL(ifail = USERARG_get_string_argument(&client_string2)); + tag_t release_stat = NULLTAG; + ITKCALL(ifail = RELSTAT_create_release_status(client_string2, &release_stat)); + if (ifail == ITK_ok) { + POM_AM__set_application_bypass(true); + ITKCALL(ifail = RELSTAT_add_release_status(release_stat, 1, &tags, true)); + POM_AM__set_application_bypass(false); + } + + MEM_free(client_string2); + + return 0; +} + +// ݴݹuidö󣬣uom_tagֵ +int uomTagSet(void* return_data) { + int ifail = ITK_ok; + int len = 2; + char **str; + + char *tag_id; + char *sj; + ifail = USERARG_get_string_argument(&tag_id); + ifail = USERARG_get_string_argument(&sj); + if (ifail == ITK_ok) { + if (len == 2) { + + tag_t tag = NULLTAG; + POM_string_to_tag(tag_id, &tag); + if (tag == NULLTAG) { + // ûҵitem + string returnStr = "ûҵitem"; + *((char**)return_data) = + (char*)MEM_alloc((returnStr.length() + 1) * sizeof(char)); + strcpy(*((char**)return_data), returnStr.c_str()); + } + else { + tag_t uom; + UOM_find_by_symbol(sj, &uom); + if (uom) { + AOM_lock(tag); + AOM_set_value_tag(tag, "uom_tag", uom); + AOM_save(tag); + AOM_unlock(tag); + string returnStr = "ֵɹ"; + *((char**)return_data) = + (char*)MEM_alloc((returnStr.length() + 1) * sizeof(char)); + strcpy(*((char**)return_data), returnStr.c_str()); + } + else + { + // ûҵӦuom + string returnStr = "ûҵӦuom"; + *((char**)return_data) = + (char*)MEM_alloc((returnStr.length() + 1) * sizeof(char)); + strcpy(*((char**)return_data), returnStr.c_str()); + } + } + } + else { + // IJuid+ֵ + string returnStr = "IJuid+ֵ"; + *((char**)return_data) = + (char*)MEM_alloc((returnStr.length() + 1) * sizeof(char)); + strcpy(*((char**)return_data), returnStr.c_str()); + } + } + else { + // userserviceʧ + string returnStr = "userserviceʧ"; + *((char**)return_data) = + (char*)MEM_alloc((returnStr.length() + 1) * sizeof(char)); + strcpy(*((char**)return_data), returnStr.c_str()); + } + return ifail; +} +// dataset_tags1 dataset_tags2 tag * ͵ +tag_t* merge_tag_arrays(tag_t* dataset_tags1, int size1, tag_t* dataset_tags2, int size2) { + // ϲĴС + if (size2 < 0) { + return NULL; + } + int merged_size = size1 + size2; + WriteLog("merged_size %d", merged_size); + // ̬ڴԴ洢ϲ + tag_t* merged_array = (tag_t*)malloc(merged_size * sizeof(tag_t)); + + if (merged_array == NULL) { + WriteLog("tag_t* merged_arrayڴʧ\n"); + } + + // dataset_tags1 Ԫصϲ + for (int i = 0; i < size1; ++i) { + merged_array[i] = dataset_tags1[i]; + } + + // dataset_tags2 Ԫصϲ + for (int i = 0; i < size2; ++i) { + merged_array[size1 + i] = dataset_tags2[i]; + } + + return merged_array; +} + +string formatDateTime(const std::chrono::system_clock::time_point& tp) { + // time_point תΪ time_t + std::time_t t = std::chrono::system_clock::to_time_t(tp); + // ʹñʱ + std::tm* local_tm = std::localtime(&t); + // һ stringstream ʽ + std::ostringstream oss; + oss << std::put_time(local_tm, "%Y-%m-%dT%H:%M:%S"); + return oss.str(); +} \ No newline at end of file diff --git a/FTMM_PLM_TO_SAPAPI/connor_itk_util.h b/FTMM_PLM_TO_SAPAPI/connor_itk_util.h new file mode 100644 index 0000000..ffb6fa5 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/connor_itk_util.h @@ -0,0 +1,80 @@ +#pragma once +#include +#include +#include +//#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +using namespace std; +//#include +//#include +//#include +//#include + +//#include +//#include +#ifdef __cplusplus +extern "C" { +#endif + +#define DOFREE(obj) \ +{ \ + if(obj) \ + { \ + MEM_free(obj); \ + obj = NULL; \ + } \ +} +void ECHO(char* format, ...); +void CreateLogFile(char* FunctionName, char** fullname); +void CreateLogFile2(char* FunctionName, char** fullname, char* fileDir); +void WriteLog(const char* format, ...); +void WriteLog2(string value); +void CloseLog(void); +string getUUid(); +void current_time(date_t* date_tag); +char* GbkToUtf8(const char* src_str); +char* Utf8ToGbk(const char* src_str); +void starTime(); +logical checkIsItemRevision(tag_t objtag); +int checkIsInType(tag_t objtag, string parentType); +int getPrefStrings(const char* preference, vector& pref_vec); +int Supor_create_signinfo_file(char* file_content, char* item_id, char** file_name); +int Connor_set_bypass(void* returnValue); +int Connor_close_bypass(void* returnValue); +int MT_add_release_status(void* return_data); +int uomTagSet(void* return_data); +tag_t* merge_tag_arrays(tag_t* dataset_tags1, int size1, tag_t* dataset_tags2, int size2); +string formatDateTime(const std::chrono::system_clock::time_point& tp); +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/FTMM_PLM_TO_SAPAPI/curl_utils.cxx b/FTMM_PLM_TO_SAPAPI/curl_utils.cxx new file mode 100644 index 0000000..a3c38af --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/curl_utils.cxx @@ -0,0 +1,197 @@ +#include "curl_utils.h" +#include + +// صڴӷյ +size_t WriteCallback(void* contents, size_t size, size_t nmemb, std::string* userp) { + size_t totalSize = size * nmemb; + userp->append((char*)contents, totalSize); + return totalSize; +} + +// صڴյӦͷ +size_t HeaderCallback(char* buffer, size_t size, size_t nitems, void* userdata) { + HeaderData* headerData = static_cast(userdata); + std::string header(buffer, size * nitems); + if (!headerData->found && header.find("x-csrf-token:") == 0) { + size_t colonPos = header.find(':'); + if (colonPos != std::string::npos) { + headerData->value = header.substr(colonPos + 1); + headerData->value.erase(0, headerData->value.find_first_not_of(" \t")); + headerData->value.erase(headerData->value.length() - 2); + headerData->found = true; // Ϊҵ + } + } + + return size * nitems; +} + +vector split_regex(const string& str, const string& pattern) { + vector tokens; + regex rgx(pattern); + sregex_token_iterator iter(str.begin(), str.end(), rgx, -1); + sregex_token_iterator end; + while (iter != end) { + tokens.push_back(*iter++); + } + return tokens; +} + +string getToken(string& url) { + CURL* curl; + CURLcode res; + //string readBuffer; + HeaderData headerData{ "", false }; + auto start = std::chrono::high_resolution_clock::now(); + curl = curl_easy_init(); + if (curl) { + char cookieFilePath[300]; + memset(cookieFilePath, 0, sizeof(cookieFilePath)); + sprintf(cookieFilePath, "%s\\cookies.txt", getenv("TEMP")); + WriteLog(cookieFilePath); + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "GET"); + curl_easy_setopt(curl, CURLOPT_USERPWD, "ZPLM_COM_USER:kfUL%B3JmMxKSvSiBgmQXVQzqrwXozmqhewNreFw"); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + struct curl_slist* headers = NULL; + headers = curl_slist_append(headers, "x-csrf-token: Fetch"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_COOKIEJAR, cookieFilePath); // 洢 Cookies + curl_easy_setopt(curl, CURLOPT_HEADER, true); + curl_easy_setopt(curl, CURLOPT_NOBODY, true); + curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, HeaderCallback); + curl_easy_setopt(curl, CURLOPT_HEADERDATA, &headerData); // HeaderData ṹ + + res = curl_easy_perform(curl); + + // 鷵ؽ + if (res != CURLE_OK) { + WriteLog("HTTP getToken failed: ", curl_easy_strerror(res)); + WriteLog("curl code : %d ", res); + } + else { + WriteLog("HTTP getToken succeed"); + } + } + curl_easy_cleanup(curl); + auto end = std::chrono::high_resolution_clock::now(); + std::chrono::duration elapsed = end - start; + std::cout << "Elapsed time: " << elapsed.count() << " seconds." << std::endl; + + return headerData.value; +} + + + + + +string postJSON(string url, string token, vector header, string body, long& http_code, string& error) +{ + string response_data = ""; + CURL* curl; + CURLcode res; + // ʼ libcurl Ự + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + + if (curl) { + char cookieFilePath[300]; + memset(cookieFilePath, 0, sizeof(cookieFilePath)); + sprintf(cookieFilePath, "%s\\cookies.txt", getenv("TEMP")); + WriteLog(cookieFilePath); + // Ҫʵ URL + curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, "POST"); + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data); + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); + curl_easy_setopt(curl, CURLOPT_DEFAULT_PROTOCOL, "https"); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L); + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L); + // ͷ + struct curl_slist* headers = NULL; + headers = curl_slist_append(headers, "Content-Type: application/json"); + if (!header.empty()) + { + for (const auto& element : header) + { + headers = curl_slist_append(headers, element.c_str()); + } + } + curl_easy_setopt(curl, CURLOPT_USERPWD, token.c_str()); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str()); + curl_easy_setopt(curl, CURLOPT_COOKIEFILE, cookieFilePath); // ȡ Cookies + + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + + + // ִ + res = curl_easy_perform(curl); + + // + if (res != CURLE_OK) + { + error = curl_easy_strerror(res); + WriteLog("curl Invoke interface failed: %s", curl_easy_strerror(res)); + WriteLog("curl code : %d ", res); + } + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + // Դ + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + } + // ȫֻ + curl_global_cleanup(); + + return response_data; +} + +string postJSON(string url, string body, long& http_code, string& error) +{ + string response_data = ""; + CURL* curl; + CURLcode res; + // ʼ libcurl Ự + curl_global_init(CURL_GLOBAL_DEFAULT); + curl = curl_easy_init(); + + if (curl) { + // Ҫʵ URL + curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); + + // ͷ + struct curl_slist* headers = NULL; + headers = curl_slist_append(headers, "Content-Type: application/json"); + curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers); + curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str()); + curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, body.size()); + // SSL֤֤ע⣺ήͰȫԣƼʹ + curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, false); + + // ûصԽӦ + curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, WriteCallback); + curl_easy_setopt(curl, CURLOPT_WRITEDATA, &response_data); + + // ִ + res = curl_easy_perform(curl); + + // + if (res != CURLE_OK) + { + error = curl_easy_strerror(res); + WriteLog("curl Invoke interface failed: %s", curl_easy_strerror(res)); + } + curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code); + // Դ + curl_slist_free_all(headers); + curl_easy_cleanup(curl); + } + // ȫֻ + curl_global_cleanup(); + + return response_data; +} \ No newline at end of file diff --git a/FTMM_PLM_TO_SAPAPI/curl_utils.h b/FTMM_PLM_TO_SAPAPI/curl_utils.h new file mode 100644 index 0000000..2a2f3a6 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/curl_utils.h @@ -0,0 +1,18 @@ +#pragma once +#define CURL_STATICLIB +#include +#include +#include +#include +#include +#include "connor_itk_util.h" + +using namespace std; +struct HeaderData { + std::string value; + bool found; // ¼Ƿҵ +}; + +string getToken(string& url); +string postJSON(string url, string token, vector header, string body, long& http_code, string& error); +string postJSON(string url, string body, long& http_code, string& error); \ No newline at end of file diff --git a/FTMM_PLM_TO_SAPAPI/main_lib.cpp b/FTMM_PLM_TO_SAPAPI/main_lib.cpp new file mode 100644 index 0000000..54de91f --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/main_lib.cpp @@ -0,0 +1,42 @@ +/** +* @headerfile tcua ͷļ +*/ +#include +#include "register_handler_methods.h" +#ifdef __cplusplus +extern "C" { +#endif + + + /** + * @fn extern "C" DLLAPI int liborigin_register_callbacks + * @return usually return ITK_ok + * @brief liborigin customization entry + * ˺й淶дdllƼ"_"ͷ + */ + DLLAPI int Comansa_BOM_TO_ERP_register_callbacks() + { + int ifail = ITK_ok; + TC_write_syslog("*******************************************************************************\n"); + TC_write_syslog("* Comansa_BOM_TO_ERP register_callbacks is starting *\n"); + TC_write_syslog("*******************************************************************************\n"); + + fprintf(stdout, "\n Comansa_BOM_TO_ERP עɹ\n"); + + + ITKCALL(ifail = CUSTOM_register_exit("Comansa_BOM_TO_ERP", "USERSERVICE_register_methods", + (CUSTOM_EXIT_ftn_t)USERSERVICE_custom_register_methods)); + fprintf(stdout, "\n Comansa_BOM_TO_ERP registering USERSERVICE_custom_register_methods completed!\n"); + + + ITKCALL(ifail = CUSTOM_register_exit("Comansa_BOM_TO_ERP", "USER_gs_shell_init_module", + (CUSTOM_EXIT_ftn_t)USERSERVICE_custom_register_handlers)); + fprintf(stdout, "\n Comansa_BOM_TO_ERP registering USERSERVICE_custom_register_handlers completed!\n"); + + + return ifail; + } + +#ifdef __cplusplus +} +#endif \ No newline at end of file diff --git a/FTMM_PLM_TO_SAPAPI/register_handler_methods.cpp b/FTMM_PLM_TO_SAPAPI/register_handler_methods.cpp new file mode 100644 index 0000000..6bd07a5 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/register_handler_methods.cpp @@ -0,0 +1,47 @@ + +#include + +#include +#include +#include"ITK_allHead.h" +#include "register_handler_methods.h" + +//̵õ +// ׼עṩ̵÷handler TC_save_msg +extern DLLAPI int USERSERVICE_custom_register_handlers(int* decision, va_list args) +{ + int ifail = ITK_ok, n = 0; + char date_buf[80], * expire_date, env[512], temp1[512], temp2[512]; + time_t now; + struct tm* p; + + *decision = ALL_CUSTOMIZATIONS; + + int status = ITK_ok; + + ////BOM + (ifail = EPM_register_action_handler("Comansa_Send_BOM_To_ERP", "Comansa_Send_BOM_To_ERP", (EPM_action_handler_t)Comansa_Send_BOM_To_ERP)); + if (ifail == 0) { + printf("Registering action handler Comansa_Send_BOM_To_ERP successful\n"); + } + else { + printf("Registering action handler Comansa_Send_BOM_To_ERP failed %d\n", ifail); + } + ////BOMnew + (ifail = EPM_register_action_handler("Comansa_Send_BOM_To_ERP_NEW", "Comansa_Send_BOM_To_ERP_NEW", (EPM_action_handler_t)Comansa_Send_BOM_To_ERP_NEW)); + if (ifail == 0) { + printf("Registering action handler Comansa_Send_BOM_To_ERP_NEW successful\n"); + } + else { + printf("Registering action handler Comansa_Send_BOM_To_ERP_NEW failed %d\n", ifail); + } + return ifail; +} + +// +//JAVAõķ +//register service method +extern DLLAPI int USERSERVICE_custom_register_methods(int* decision, va_list args) +{ + return 0; +} \ No newline at end of file diff --git a/FTMM_PLM_TO_SAPAPI/register_handler_methods.h b/FTMM_PLM_TO_SAPAPI/register_handler_methods.h new file mode 100644 index 0000000..0f5da91 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/register_handler_methods.h @@ -0,0 +1,19 @@ +#ifndef REGISTER_HANDLER_METHODS +#define REGISTER_HANDLER_METHODS + +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + + extern DLLAPI int USERSERVICE_custom_register_handlers(int*, va_list); + extern DLLAPI int USERSERVICE_custom_register_methods(int* decision, va_list args); + + +#ifdef __cplusplus +} +#endif + +#endif + diff --git a/FTMM_PLM_TO_SAPAPI/string_utils.cxx b/FTMM_PLM_TO_SAPAPI/string_utils.cxx new file mode 100644 index 0000000..0b26e98 --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/string_utils.cxx @@ -0,0 +1,289 @@ +/*================================================================================================================== + Copyright(c) 2012 ORIGIN. + Unpublished - All rights reserved +==================================================================================================================== +File description: + Filename: string_utils.c + Module : Common module. + + This file includes some operations of the string. + +==================================================================================================================== +Date Name Description of Change +3-Feb-2015 Ray li Initialize creation +$HISTORY$ +===================================================================================================================*/ +#ifndef _cplusplus +#ifndef _CRT_SECURE_NO_DEPRECATE +#define _CRT_SECURE_NO_DEPRECATE +#endif +#endif + +#include +#include +#include +#include +#include + +#include "string_utils.h" + +char* GSTR_clone( char **dst, const char *src ) +{ + char *retVal = NULL; + int srcLen = 0; + + *dst = NULL; + if (src == NULL) + return NULL; + + srcLen = (int)tc_strlen( src ) + 1; + *dst = (char*)MEM_alloc( srcLen * sizeof(char) ); + retVal = tc_strncpy( *dst, src, srcLen ); + (*dst)[srcLen - 1] = '\0'; + + return retVal; +} + +char* GSTR_copy( char *dst, const char *src, int dstSize ) +{ + char *retVal = tc_strncpy( dst, src, dstSize ); + dst[dstSize - 1] = '\0'; + return retVal; +} + +char* GSTR_int_to_string( char **dst, int value ) +{ + char strVal[128 + 1]; + + *dst = NULL; + memset( strVal, 0, sizeof(strVal)/sizeof(char) ); + sprintf( strVal, "%d", value ); + + return GSTR_clone( dst, strVal ); +} + +void GSTR_format_int_to_string( char *dst, int digitNum, int value ) +{ + char sNum[WSO_desc_size_c + 1]; + sprintf( sNum, "%%0%dd", digitNum ); + sprintf( dst, sNum, value ); +} + +void GSTR_format_string( const char *dst, int m, const char *fill_char, char **out ) +{ + char sNum[WSO_name_size_c + 1] = {0}; + char sNew[WSO_name_size_c + 1] = {0}; + sprintf( sNum, "%%%d.%ds", m, m ); + sprintf( sNew, sNum, dst ); + STRNG_replace_str( sNew, " ", fill_char, out ); +} + + +char* GSTR_string_append( const char *s1, const char *s2 ) +{ + char *s = NULL; + if (s1 == NULL || s2 == NULL) + { + GSTR_clone(&s, s1 == NULL ? (s2 == NULL ? "" : s2) : s1 ); + } + else + { + int size = (int)tc_strlen(s1) + (int)tc_strlen(s2) + 1; + s = (char *)MEM_alloc( size ); + tc_strcpy( s, s1 ); + tc_strcat( s, s2 ); + s[size - 1] = '\0'; + } + return s; +} + +logical GSTR_is_float(const char *str) +{ + logical isfloat = true; + char *pStr = (char *)str; + logical hasPositive = false; + logical hasMinus = false; + logical hasDot = false; + + if (str == NULL) + return false; + + while (*pStr != '\0' && isfloat == true) + { + if ( (*pStr >= '0' && *pStr <= '9')) + { + //continue; + } + else if ( *pStr == '+' ) + { + isfloat = (hasPositive ? false : (hasPositive = true)); + } + else if ( *pStr == '-' ) + { + isfloat = (hasMinus ? false : (hasMinus = true)); + } + else if ( *pStr == '.' ) + { + isfloat = (hasDot ? false : (hasDot = true)); + } + else + isfloat = false; + + pStr ++; + } + return isfloat; +} + +logical GSTR_is_number(const char *str) +{ + logical is_number = true; + char *pStr = (char *)str; + if (str == NULL) + return false; + + while (*pStr != '\0') + { + if ( !( (*pStr >= '0' && *pStr <= '9') || *pStr == '-' ) ) + { + is_number = false; + break; + } + pStr ++; + } + return is_number; +} + +logical GSTR_is_ascii(char ch) +{ + return ((unsigned int)ch) < 128; +} + +int GSTR_trim_l( char *str, char s ) +{ + int count = 0; + char *pointer = str, *poffset = NULL; + if (str == NULL || str[0] == '\0') + return 0; + + while ( *pointer != '\0' ) + { + if ( *pointer != s ) + { + break; + } + count++; + pointer++; + } + if (count == 0) + return 0; + + poffset = str + count; + pointer = str; + while ( *poffset != '\0' ) + { + *pointer = *poffset; + pointer ++; + poffset ++; + } + *pointer = '\0'; + + return count; +} + +int GSTR_trim_r( char *str, char s ) +{ + int count = 0; + char *pointer = NULL; + if (str == NULL || str[0] == '\0') + return 0; + + pointer = str + ((int) strlen(str) - 1); + + while ( pointer != str ) + { + if ( *pointer != s ) + { + break; + } + + *pointer = '\0'; + + count++; + pointer--; + } + + return count; +} + +void GSTR_trim_float( char *floatValue ) +{ + if ( !IS_EMPTY(floatValue) && tc_strstr(floatValue, ".") != NULL ) + { + int len = 0; + GSTR_trim_r(floatValue, '0'); + len = (int)tc_strlen(floatValue); + if (floatValue[ len - 1 ] == '.') + floatValue[ len - 1 ] = '\0'; + } +} + +string TrimString(string strArg) +{ + size_t index1 = 0; + index1 = strArg.find_first_not_of(' '); + if (index1 != string::npos) + strArg.erase(strArg.begin(), strArg.begin() + index1); + index1 = strArg.find_last_not_of(' '); + if (index1 != string::npos) + strArg.erase(strArg.begin() + index1 + 1); + return strArg; +} + +void Split(string strArg, string spliter, vector& ans) +{ + + ans.clear(); + + size_t index0; + string one_arg; + + if (strArg.find_first_not_of(" ") == string::npos) + strArg = ""; + + + while (strArg.size() > 0) + { + + index0 = strArg.find(spliter); + + if (index0 != string::npos) + { + + one_arg = strArg.substr(0, index0); + strArg = strArg.substr(index0 + spliter.size()); + + ans.push_back(one_arg); + } + else + { + + ans.push_back(strArg); + break; + } + } +} + + +void RemoveLiner(string& in, string& out) +{ + char buf[BUFSIZ] = ""; + for (int i = 0; i < (int)in.size(); i++) + { + if (in[i] == '\n') + continue; + else + sprintf(buf, "%s%c", buf, in[i]); + } + out.assign(buf); +} + diff --git a/FTMM_PLM_TO_SAPAPI/string_utils.h b/FTMM_PLM_TO_SAPAPI/string_utils.h new file mode 100644 index 0000000..39546cb --- /dev/null +++ b/FTMM_PLM_TO_SAPAPI/string_utils.h @@ -0,0 +1,128 @@ +/*===================================================================================================================== + Copyright(c) 2005 ORIGIN PLM Software Corp. All rights reserved. + Unpublished - All rights reserved +======================================================================================================================= +File description: + Filename: string_utils.h + Module : Common module. + + This file includes some operations of the string. + +======================================================================================================================= +Date Name Description of Change +14-Jul-2009 Ray Li Initialize creation +$HISTORY$ +=====================================================================================================================*/ +#ifndef STRING_UTILS_H +#define STRING_UTILS_H +#include +#include +#include +using namespace std; +#ifdef __cplusplus + extern "C" + { +#endif + +// @{{ String assister +#define IS_NULL(S) ((S)==NULL) +#define IS_EMPTY(S) (((S)==NULL) || !(*(S))) +// @}} + void Split( string strArg, string spliter, vector &ans ); + /** + * Clones the string. + * @param dst - the output string. + * @param src - the string to be cloned. + * @return - the destinatin string pointer. + */ + extern char* GSTR_clone( char **dst, const char *src ); + + /** + * Copy safely the string with null end. + * @param dst - the output string. + * @param src - the string to be cloned. + * @param dstSize - the size of output string. + * @return - the destinatin string pointer. + */ + extern char *GSTR_copy( char *dst, const char *src, int dstSize ); + + /** + * Converts int to string. + * @param dst - the output string. + * @param value - the int to be cloned. + * @return - the destinatin string pointer. + */ + extern char* GSTR_int_to_string( char **dst, int value ); + + /** + * Formats the int/string value as string. + * @param dst - the destination string. + * @param digitNum - the digit number of the value. + * @param value - the value to be converted. + * @return - N/A. + */ + extern void GSTR_format_int_to_string( char *dst, int digitNum, int value ); + extern void GSTR_format_string( const char *dst, int m, const char *fill_char, char **out ); + + /** + * Appends the strings( never null returned ) + * @param s1 - string 1 + * @param s2 - string 2 + * @return - new string + */ + extern char* GSTR_string_append( const char *s1, const char *s2 ); + + /** + * Whether the string is float type + * @param str - The string + * + * NOTE: it's only check whether each word is in "+-.0123456789", not care the float with "E" or the float rule, + * like "00-1.+01", it will return true. + * @return - return true if it is one. + */ + extern logical GSTR_is_float(const char *str); + + /** + * Whether all char of the string are number + * @param str - The string + * + * NOTE: it's only check whether each word is in "0123456789" + * @return - return true if it is one. + */ + extern logical GSTR_is_number(const char *str); + + /** + * Is ascii char + * @param ch - ascii char + * @return - return true if it is. + */ + extern logical GSTR_is_ascii(char ch); + + /** + * Trims the string's prefix. + * @param str - The string + * @param s - The char + * + * @return - count. + */ + extern int GSTR_trim_l( char *str, char s ); + extern int GSTR_trim_r( char *str, char s ); + + /** + * Remove the zero. + * For Example: + * floatValue="50.00" -> = "50" + * floatValue="50.0100" -> = "50.01" + * @return - count. + */ + extern void GSTR_trim_float( char *floatValue ); + + extern string TrimString(string strArg); + extern void Split(string strArg, string spliter, vector& ans); + extern void RemoveLiner(string& in, string& out); +#ifdef __cplusplus + } +#endif + + +#endif //STRING_UTILS_H