first commit

main
李建辉 1 month ago
commit c35092bbf0

63
.gitattributes vendored

@ -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

364
.gitignore vendored

@ -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

@ -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

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
<Configuration>Debug</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Debug|x64">
<Configuration>Debug</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
<ProjectConfiguration Include="Release|x64">
<Configuration>Release</Configuration>
<Platform>x64</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>16.0</VCProjectVersion>
<Keyword>Win32Proj</Keyword>
<ProjectGuid>{4c7d48c0-184c-4d80-9a32-2a52f828fe82}</ProjectGuid>
<RootNamespace>FTMMPLMTOSAPAPI</RootNamespace>
<WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion>
<ProjectName>Comansa_BOM_TO_ERP</ProjectName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>DynamicLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v142</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>Unicode</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="ExtensionSettings">
</ImportGroup>
<ImportGroup Label="Shared">
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<LinkIncremental>false</LinkIncremental>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<GenerateDebugInformation>true</GenerateDebugInformation>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>
</SDLCheck>
<PreprocessorDefinitions>WIN32; NDEBUG; _CONSOLE; IPLIB=none ;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>Default</ConformanceMode>
<AdditionalIncludeDirectories>D:\source\锡压\SignOff_itk\curl\include;D:\source\科曼萨\环境\include;D:\source\科曼萨\环境\include_cpp;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<LanguageStandard_C>Default</LanguageStandard_C>
<DisableSpecificWarnings>4996</DisableSpecificWarnings>
<BufferSecurityCheck>false</BufferSecurityCheck>
<PrecompiledHeader />
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>D:\source\科曼萨\环境\lib\*.lib;D:\source\科曼萨\环境\curl\lib\*.lib;libcurl_a.lib;Ws2_32.lib;Wldap32.lib;Crypt32.lib;Advapi32.lib;Normaliz.lib;%(AdditionalDependencies)</AdditionalDependencies>
<IgnoreSpecificDefaultLibraries>libuser_exits.ar.lib</IgnoreSpecificDefaultLibraries>
<AdditionalLibraryDirectories>D:\source\科曼萨\环境\curl\lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<UACExecutionLevel>RequireAdministrator</UACExecutionLevel>
<UACUIAccess>true</UACUIAccess>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="cJSON.c" />
<ClCompile Include="connor_itk_util.cpp" />
<ClCompile Include="KSM_ERP_BOM.cpp" />
<ClCompile Include="curl_utils.cxx" />
<ClCompile Include="main_lib.cpp" />
<ClCompile Include="register_handler_methods.cpp" />
<ClCompile Include="string_utils.cxx" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="cJSON.h" />
<ClInclude Include="connor_itk_util.h" />
<ClInclude Include="curl_utils.h" />
<ClInclude Include="ITK_allHead.h" />
<ClInclude Include="register_handler_methods.h" />
<ClInclude Include="string_utils.h" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

@ -0,0 +1,47 @@
#pragma once
#include "connor_itk_util.h"
#include <ctime>
#include <vector>
#include <locale>
#include <codecvt>
#include <ae/dataset.h>
#include <iostream>
#include <regex>
#include <list>
#include <set>
#include <stdlib.h>
#include <iostream>
#include <fstream>
#include <tc/folder.h>
#include <ict/ict_userservice.h>
#include <epm/epm_toolkit_tc_utils.h>
#include <tccore/aom.h>
#include <tccore/aom_prop.h>
#include <tccore/item.h>
#include <bom/bom.h>
#include <ps/ps.h>
#include <ps/vrule.h>
#include <sstream>
#include <cfm\cfm.h>
#include <tccore/grm.h>
#include <epm/epm.h>
#include <sa/sa.h>
#include <map>
#include <epm/signoff.h>
#include <tccore/custom.h>
#include "cJSON.h"
#include "curl_utils.h"
#include "string_utils.h"
#include <tc/envelope.h>
#include <ae/dataset.h>
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);

@ -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<tag_t> &child_vect, char* secondaryType, vector<string> 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<string> 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<tag_t> 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<string> 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<string> attr_vec;
Split(attrs_vec[j].c_str(), "=", attr_vec);
if (strstr(attr_vec[1].c_str(), ".") != NULL) {
vector<string> 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<string> attr_vec;
Split(values[0], "=", attr_vec);
if (strstr(attr_vec[1].c_str(), ".") != NULL) {
vector<string> 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<string> 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<string> 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<string> attr_vec;
Split(attrs_vec[j].c_str(), "=", attr_vec);
if (strstr(attr_vec[1].c_str(), ".") != NULL) {
vector<string> 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<string> attr_vec;
Split(json_vec[1].c_str(), "=", attr_vec);
if (strstr(attr_vec[1].c_str(), ".") != NULL) {
vector<string> 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<tag_t>& 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<string> 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<string> 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<string> attr_vec;
Split(attrs_vec[j].c_str(), "=", attr_vec);
if (strstr(attr_vec[1].c_str(), ".") != NULL) {
vector<string> 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<string> attr_vec;
Split(json_vec[1].c_str(), "=", attr_vec);
if (strstr(attr_vec[1].c_str(), ".") != NULL) {
vector<string> 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<tag_t> 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<string> 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<string> attr_vec;
Split(attrs_vec[j].c_str(), "=", attr_vec);
if (strstr(attr_vec[1].c_str(), ".") != NULL) {
vector<string> 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<string> attr_vec;
Split(values[0], "=", attr_vec);
if (strstr(attr_vec[1].c_str(), ".") != NULL) {
vector<string> 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;
}

@ -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 <string.h>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <float.h>
#include <limits.h>
#include <ctype.h>
#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. */
}

@ -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

@ -0,0 +1,628 @@
#pragma warning(disable: 4996)
#include <wchar.h>
#include <string.h>
#ifdef WIN32
#include <io.h>
#include <direct.h>
#else
#include <unistd.h>
#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(&ltime);
today = localtime(&ltime);
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);
}
/**
*
* 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<string>& 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 {
// 传过来的不是uid+数值
string returnStr = "传过来的不是uid+数值";
*((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();
}

@ -0,0 +1,80 @@
#pragma once
#include <stdio.h>
#include <Windows.h>
#include <stdlib.h>
//#include <io.h>
#include <time.h>
#include <string>
#include <vector>
#include<algorithm>
#include <epm/epm.h>
#include <epm/epm_toolkit_tc_utils.h>
#include <ict/ict_userservice.h>
#include <tccore/item.h>
#include <ae/ae.h>
#include <tc/folder.h>
#include <tccore/aom.h>
#include <sa/sa.h>
#include <tccore/aom_prop.h>
#include <property/prop_errors.h>
#include <tccore/workspaceobject.h>
#include <tc/preferences.h>
#include <tccore//grm.h>
#include <tccore/grmtype.h>
#include <sa/am.h>
#include <cfm/cfm.h>
#include <bom/bom.h>
#include <tccore/uom.h>
#include <ps/ps.h>
#include <epm/signoff.h>
#include <fclasses/tc_date.h>
#include <objbase.h>
#include <iostream>
#include <chrono>
#include <iomanip>
#include <sstream>
#include <algorithm>
using namespace std;
//#include <tccore/imantype.h>
//#include <textsrv/textserver.h>
//#include <user_exits/epm_toolkit_utils.h>
//#include <ss/ss_errors.h>
//#include <direct.h>
//#include <unistd.h>
#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<string>& 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

@ -0,0 +1,197 @@
#include "curl_utils.h"
#include <chrono>
// 回调函数,用于处理从服务器接收到的数据
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<HeaderData*>(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<string> split_regex(const string& str, const string& pattern) {
vector<string> 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<double> elapsed = end - start;
std::cout << "Elapsed time: " << elapsed.count() << " seconds." << std::endl;
return headerData.value;
}
string postJSON(string url, string token, vector<string> 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;
}

@ -0,0 +1,18 @@
#pragma once
#define CURL_STATICLIB
#include <vector>
#include <iostream>
#include <curl/curl.h>
#include <string>
#include <regex>
#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<string> header, string body, long& http_code, string& error);
string postJSON(string url, string body, long& http_code, string& error);

@ -0,0 +1,42 @@
/**
* @headerfile tcua
*/
#include <server_exits/user_server_exits.h>
#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

@ -0,0 +1,47 @@
#include <server_exits/user_server_exits.h>
#include <tccore/item_msg.h>
#include <epm/epm.h>
#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);
}
////BOM传递new
(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;
}

@ -0,0 +1,19 @@
#ifndef REGISTER_HANDLER_METHODS
#define REGISTER_HANDLER_METHODS
#include <epm/epm.h>
#include <tccore/custom.h>
#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

@ -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 <fclasses/tc_string.h>
#include <tc/tc_util.h>
#include <tccore/workspaceobject.h>
#include <stdlib.h>
#include <ctype.h>
#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<string>& 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);
}

@ -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 <string>
#include <map>
#include <vector>
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<string> &ans );
/**
* Clones the string.
* @param dst - <OF> the output string.
* @param src - <I> 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 - <O> the output string.
* @param src - <I> the string to be cloned.
* @param dstSize - <I> 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 - <OF> the output string.
* @param value - <I> 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 - <O> the destination string.
* @param digitNum - <I> the digit number of the value.
* @param value - <I> 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 - <I> string 1
* @param s2 - <I> string 2
* @return - <OF> new string
*/
extern char* GSTR_string_append( const char *s1, const char *s2 );
/**
* Whether the string is float type
* @param str - <I> 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 - <I> 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 - <I> ascii char
* @return - return true if it is.
*/
extern logical GSTR_is_ascii(char ch);
/**
* Trims the string's prefix.
* @param str - <I> The string
* @param s - <I> 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<string>& ans);
extern void RemoveLiner(string& in, string& out);
#ifdef __cplusplus
}
#endif
#endif //STRING_UTILS_H
Loading…
Cancel
Save