21 Commits

Author SHA1 Message Date
lnk
2161629fe0 修改编译脚本适配pqdif,同步61850日志上送逻辑 2026-05-19 14:07:44 +08:00
lnk
f879978e62 修改台账更新和添加升级接口 2026-05-08 09:55:34 +08:00
lnk
10a24450c7 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2026-04-29 14:55:19 +08:00
ebefd6b2ae 新增PQDIF解析线程,新增各项PQDIF解析逻辑 2026-04-29 13:35:49 +08:00
lnk
845d2c551b resolve conflict: keep LFtid1056.rar 2026-04-24 16:24:28 +08:00
lnk
54b0d68c24 修改通知 2026-04-24 16:22:15 +08:00
33de63cdc6 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2026-04-22 10:40:28 +08:00
3f3c706b0d 新增了PQDIF补招线程,导入了新的lib库 2026-04-22 10:40:19 +08:00
lnk
ea176eceaf add interface 2026-04-02 16:23:15 +08:00
lnk
2dab1369f3 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2026-04-01 15:30:57 +08:00
lnk
b11105f91c add interface 2026-04-01 15:30:52 +08:00
dfe0f2e5e2 新增文件删除 文件上传 目录创建 目录删除 2026-03-31 09:44:17 +08:00
lnk
15cbbd1c24 fix cloudtopic msg proc 2026-03-30 15:32:14 +08:00
lnk
69accad937 finish add interface 2026-03-13 16:29:46 +08:00
lnk
8e41e3f4d8 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2026-03-13 16:07:38 +08:00
lnk
af937a8360 add interface 2026-03-13 16:07:22 +08:00
3d589c5042 删除了测试用的注释 2026-03-09 19:08:02 +08:00
f727f9ee9c 修改了装置重启方式,去除了外部调用的校验流程,现在直接在内部自动完成。
新增了装置升级的正式流程。
2026-03-09 19:06:56 +08:00
93def18fbd 添加了装置预升级校验流程 2026-03-05 20:56:14 +08:00
bf1eccf436 新增了装置重启命令的校验和执行流程。 2026-03-05 15:38:21 +08:00
852245f8ac 前置新增了装置心跳传输流程,每30秒自动发送一次心跳报文 2026-03-05 13:53:17 +08:00
94 changed files with 37598 additions and 440 deletions

BIN
LFtid1056--切分备份.zip Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -86,6 +86,10 @@
<ClCompile Include="cloudfront\code\worker.cpp" />
<ClCompile Include="dealMsg.cpp" />
<ClCompile Include="main_thread.cpp" />
<ClCompile Include="pqdif\include\cjson.c" />
<ClCompile Include="pqdif\PQDIF.cpp" />
<ClCompile Include="pqdif_semantic_ids.cpp" />
<ClCompile Include="pqdif_thread_processor.cpp" />
<ClCompile Include="PQSMsg.cpp" />
</ItemGroup>
<ItemGroup>
@@ -267,6 +271,44 @@
<ClInclude Include="cloudfront\code\tinyxml2.h" />
<ClInclude Include="cloudfront\code\worker.h" />
<ClInclude Include="dealMsg.h" />
<ClInclude Include="pqdif\include\cjson.h" />
<ClInclude Include="pqdif\include\el_base.h" />
<ClInclude Include="pqdif\include\el_coll.h" />
<ClInclude Include="pqdif\include\el_scal.h" />
<ClInclude Include="pqdif\include\el_vect.h" />
<ClInclude Include="pqdif\include\pcn_base.h" />
<ClInclude Include="pqdif\include\pcn_flat.h" />
<ClInclude Include="pqdif\include\pqbytearray.h" />
<ClInclude Include="pqdif\include\pqdfacty.h" />
<ClInclude Include="pqdif\include\PQDIF_classes.h" />
<ClInclude Include="pqdif\include\pqdif_custom_1.h" />
<ClInclude Include="pqdif\include\pqdif_custom_2.h" />
<ClInclude Include="pqdif\include\pqdif_id.h" />
<ClInclude Include="pqdif\include\pqdif_lg.h" />
<ClInclude Include="pqdif\include\pqdif_ph.h" />
<ClInclude Include="pqdif\include\pqdinfo.h" />
<ClInclude Include="pqdif\include\pqdsupport.h" />
<ClInclude Include="pqdif\include\pqptrarray.h" />
<ClInclude Include="pqdif\include\proc_bas.h" />
<ClInclude Include="pqdif\include\proc_not.h" />
<ClInclude Include="pqdif\include\proc_zlib.h" />
<ClInclude Include="pqdif\include\rec_base.h" />
<ClInclude Include="pqdif\include\rec_container.h" />
<ClInclude Include="pqdif\include\rec_datasource.h" />
<ClInclude Include="pqdif\include\rec_general.h" />
<ClInclude Include="pqdif\include\rec_observ.h" />
<ClInclude Include="pqdif\include\rec_settings.h" />
<ClInclude Include="pqdif\include\ser_alloc.h" />
<ClInclude Include="pqdif\include\ser_cont_el.h" />
<ClInclude Include="pqdif\include\ser_iter_el.h" />
<ClInclude Include="pqdif\include\str_base.h" />
<ClInclude Include="pqdif\include\str_chnk.h" />
<ClInclude Include="pqdif\include\str_flat.h" />
<ClInclude Include="pqdif\include\zconf.h" />
<ClInclude Include="pqdif\include\zlib.h" />
<ClInclude Include="pqdif\PQDIF.h" />
<ClInclude Include="pqdif_semantic_ids.h" />
<ClInclude Include="pqdif_thread_processor.h" />
<ClInclude Include="PQSMsg.h" />
</ItemGroup>
<ItemGroup>
@@ -299,23 +341,263 @@
<Library Include="cloudfront\lib\librocketmq.so" />
<Library Include="cloudfront\lib\libssl.so" />
<Library Include="libuv.a" />
<Library Include="pqdif\lib\libpqdiflib.a" />
<Library Include="pqdif\lib\libz.a" />
</ItemGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<AdditionalIncludeDirectories>$(RemoteRootDir)/cloudfront/code;$(RemoteRootDir)/cloudfront/code/nlohmann;$(RemoteRootDir)/cloudfront/code/curl;$(RemoteRootDir)/cloudfront/code/log4cplus;$(RemoteRootDir)/cloudfront/code/rocketmq;$(RemoteRootDir)/lib/libuv-v1.51.0/include;$(RemoteRootDir);D:\Git代码\frontlinux\LFtid1056\cloudfront\code;D:\Git代码\frontlinux\LFtid1056;D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;D:\Git代码\frontlinux\LFtid1056\cloudfront\code\curl;D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;D:\Git代码\frontlinux\LFtid1056\cloudfront\code\nlohmann;D:\Git代码\frontlinux\LFtid1056\cloudfront\code\rocketmq;./cloudfront/code;./cloudfront/code/nlohmann;./cloudfront/code/curl;./cloudfront/code/log4cplus;./cloudfront/code/rocketmq;./lib/libuv-v1.51.0/include;.;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalIncludeDirectories>$(RemoteRootDir);
$(RemoteRootDir)/cloudfront/code;
$(RemoteRootDir)/cloudfront/code/log4cplus;
$(RemoteRootDir)/cloudfront/code/log4cplus/include;
$(RemoteRootDir)/lib/libuv-v1.51.0/include;
$(RemoteRootDir)/pqdif;
$(RemoteRootDir)/pqdif/include;
D:\Git代码\frontlinux\LFtid1056;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus\include;
D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;
D:\Git代码\frontlinux\LFtid1056\pqdif;
D:\Git代码\frontlinux\LFtid1056\pqdif\include;
.;
./cloudfront/code;
./cloudfront/code/log4cplus;
./cloudfront/code/log4cplus/include;
./lib/libuv-v1.51.0/include;
./pqdif;
./pqdif/include;
%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
<AdditionalOptions>-std=c++11 -O2 -static-libstdc++ -static-libgcc -pthread %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<AdditionalLibraryDirectories>D:\Git代码\frontlinux;D:\Git代码\frontlinux\LFtid1056\cloudfront\lib;$(RemoteRootDir)/cloudfront/lib;$(RemoteRootDir);/usr/lib64;/usr/local/lib;D:\Git代码\frontlinux\LFtid1056;./cloudfront/lib;./usr/lib64;./usr/local/lib;%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
<AdditionalLibraryDirectories>/root/projects/LFtid1056/pqdif/lib</AdditionalLibraryDirectories>
<LibraryDependencies>uv;pthread;dl;rt;stdc++fs;z;%(LibraryDependencies)</LibraryDependencies>
<AdditionalDependencies>/root/projects/LFtid1056/cloudfront/lib/librocketmq.a;/root/projects/LFtid1056/cloudfront/lib/libcurl.so;/root/projects/LFtid1056/cloudfront/lib/libssl.so;/root/projects/LFtid1056/cloudfront/lib/libcrypto.so;/root/projects/LFtid1056/cloudfront/lib/liblog4cplus.so;/root/projects/LFtid1056/libuv.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib %(AdditionalOptions)</AdditionalOptions>
<AdditionalDependencies>/root/projects/LFtid1056/pqdif/lib/libpqdiflib.a;/root/projects/LFtid1056/pqdif/lib/libz.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib -Wl,--start-group /root/projects/LFtid1056/pqdif/lib/libpqdiflib.a /root/projects/LFtid1056/pqdif/lib/libz.a -Wl,--end-group %(AdditionalOptions)</AdditionalOptions>
</Link>
<PreLinkEvent>
<Command>
</Command>
</PreLinkEvent>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM'">
<ClCompile>
<AdditionalIncludeDirectories>$(RemoteRootDir);
$(RemoteRootDir)/cloudfront/code;
$(RemoteRootDir)/cloudfront/code/log4cplus;
$(RemoteRootDir)/cloudfront/code/log4cplus/include;
$(RemoteRootDir)/lib/libuv-v1.51.0/include;
$(RemoteRootDir)/pqdif;
$(RemoteRootDir)/pqdif/include;
D:\Git代码\frontlinux\LFtid1056;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus\include;
D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;
D:\Git代码\frontlinux\LFtid1056\pqdif;
D:\Git代码\frontlinux\LFtid1056\pqdif\include;
.;
./cloudfront/code;
./cloudfront/code/log4cplus;
./cloudfront/code/log4cplus/include;
./lib/libuv-v1.51.0/include;
./pqdif;
./pqdif/include;
%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>/root/projects/LFtid1056/pqdif/lib/libpqdiflib.a;/root/projects/LFtid1056/pqdif/lib/libz.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib -Wl,--start-group /root/projects/LFtid1056/pqdif/lib/libpqdiflib.a /root/projects/LFtid1056/pqdif/lib/libz.a -Wl,--end-group %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>/root/projects/LFtid1056/pqdif/lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM'">
<ClCompile>
<AdditionalIncludeDirectories>$(RemoteRootDir);
$(RemoteRootDir)/cloudfront/code;
$(RemoteRootDir)/cloudfront/code/log4cplus;
$(RemoteRootDir)/cloudfront/code/log4cplus/include;
$(RemoteRootDir)/lib/libuv-v1.51.0/include;
$(RemoteRootDir)/pqdif;
$(RemoteRootDir)/pqdif/include;
D:\Git代码\frontlinux\LFtid1056;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus\include;
D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;
D:\Git代码\frontlinux\LFtid1056\pqdif;
D:\Git代码\frontlinux\LFtid1056\pqdif\include;
.;
./cloudfront/code;
./cloudfront/code/log4cplus;
./cloudfront/code/log4cplus/include;
./lib/libuv-v1.51.0/include;
./pqdif;
./pqdif/include;
%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>/root/projects/LFtid1056/pqdif/lib/libpqdiflib.a;/root/projects/LFtid1056/pqdif/lib/libz.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib -Wl,--start-group /root/projects/LFtid1056/pqdif/lib/libpqdiflib.a /root/projects/LFtid1056/pqdif/lib/libz.a -Wl,--end-group %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>/root/projects/LFtid1056/pqdif/lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|ARM64'">
<ClCompile>
<AdditionalIncludeDirectories>$(RemoteRootDir);
$(RemoteRootDir)/cloudfront/code;
$(RemoteRootDir)/cloudfront/code/log4cplus;
$(RemoteRootDir)/cloudfront/code/log4cplus/include;
$(RemoteRootDir)/lib/libuv-v1.51.0/include;
$(RemoteRootDir)/pqdif;
$(RemoteRootDir)/pqdif/include;
D:\Git代码\frontlinux\LFtid1056;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus\include;
D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;
D:\Git代码\frontlinux\LFtid1056\pqdif;
D:\Git代码\frontlinux\LFtid1056\pqdif\include;
.;
./cloudfront/code;
./cloudfront/code/log4cplus;
./cloudfront/code/log4cplus/include;
./lib/libuv-v1.51.0/include;
./pqdif;
./pqdif/include;
%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>/root/projects/LFtid1056/pqdif/lib/libpqdiflib.a;/root/projects/LFtid1056/pqdif/lib/libz.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib -Wl,--start-group /root/projects/LFtid1056/pqdif/lib/libpqdiflib.a /root/projects/LFtid1056/pqdif/lib/libz.a -Wl,--end-group %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>/root/projects/LFtid1056/pqdif/lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|ARM64'">
<ClCompile>
<AdditionalIncludeDirectories>$(RemoteRootDir);
$(RemoteRootDir)/cloudfront/code;
$(RemoteRootDir)/cloudfront/code/log4cplus;
$(RemoteRootDir)/cloudfront/code/log4cplus/include;
$(RemoteRootDir)/lib/libuv-v1.51.0/include;
$(RemoteRootDir)/pqdif;
$(RemoteRootDir)/pqdif/include;
D:\Git代码\frontlinux\LFtid1056;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus\include;
D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;
D:\Git代码\frontlinux\LFtid1056\pqdif;
D:\Git代码\frontlinux\LFtid1056\pqdif\include;
.;
./cloudfront/code;
./cloudfront/code/log4cplus;
./cloudfront/code/log4cplus/include;
./lib/libuv-v1.51.0/include;
./pqdif;
./pqdif/include;
%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>/root/projects/LFtid1056/pqdif/lib/libpqdiflib.a;/root/projects/LFtid1056/pqdif/lib/libz.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib -Wl,--start-group /root/projects/LFtid1056/pqdif/lib/libpqdiflib.a /root/projects/LFtid1056/pqdif/lib/libz.a -Wl,--end-group %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>/root/projects/LFtid1056/pqdif/lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<AdditionalIncludeDirectories>$(RemoteRootDir);
$(RemoteRootDir)/cloudfront/code;
$(RemoteRootDir)/cloudfront/code/log4cplus;
$(RemoteRootDir)/cloudfront/code/log4cplus/include;
$(RemoteRootDir)/lib/libuv-v1.51.0/include;
$(RemoteRootDir)/pqdif;
$(RemoteRootDir)/pqdif/include;
D:\Git代码\frontlinux\LFtid1056;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus\include;
D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;
D:\Git代码\frontlinux\LFtid1056\pqdif;
D:\Git代码\frontlinux\LFtid1056\pqdif\include;
.;
./cloudfront/code;
./cloudfront/code/log4cplus;
./cloudfront/code/log4cplus/include;
./lib/libuv-v1.51.0/include;
./pqdif;
./pqdif/include;
%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>/root/projects/LFtid1056/pqdif/lib/libpqdiflib.a;/root/projects/LFtid1056/pqdif/lib/libz.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib -Wl,--start-group /root/projects/LFtid1056/pqdif/lib/libpqdiflib.a /root/projects/LFtid1056/pqdif/lib/libz.a -Wl,--end-group %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>/root/projects/LFtid1056/pqdif/lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x86'">
<ClCompile>
<AdditionalIncludeDirectories>$(RemoteRootDir);
$(RemoteRootDir)/cloudfront/code;
$(RemoteRootDir)/cloudfront/code/log4cplus;
$(RemoteRootDir)/cloudfront/code/log4cplus/include;
$(RemoteRootDir)/lib/libuv-v1.51.0/include;
$(RemoteRootDir)/pqdif;
$(RemoteRootDir)/pqdif/include;
D:\Git代码\frontlinux\LFtid1056;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus\include;
D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;
D:\Git代码\frontlinux\LFtid1056\pqdif;
D:\Git代码\frontlinux\LFtid1056\pqdif\include;
.;
./cloudfront/code;
./cloudfront/code/log4cplus;
./cloudfront/code/log4cplus/include;
./lib/libuv-v1.51.0/include;
./pqdif;
./pqdif/include;
%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>/root/projects/LFtid1056/pqdif/lib/libpqdiflib.a;/root/projects/LFtid1056/pqdif/lib/libz.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib -Wl,--start-group /root/projects/LFtid1056/pqdif/lib/libpqdiflib.a /root/projects/LFtid1056/pqdif/lib/libz.a -Wl,--end-group %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>/root/projects/LFtid1056/pqdif/lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x86'">
<ClCompile>
<AdditionalIncludeDirectories>$(RemoteRootDir);
$(RemoteRootDir)/cloudfront/code;
$(RemoteRootDir)/cloudfront/code/log4cplus;
$(RemoteRootDir)/cloudfront/code/log4cplus/include;
$(RemoteRootDir)/lib/libuv-v1.51.0/include;
$(RemoteRootDir)/pqdif;
$(RemoteRootDir)/pqdif/include;
D:\Git代码\frontlinux\LFtid1056;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus;
D:\Git代码\frontlinux\LFtid1056\cloudfront\code\log4cplus\include;
D:\Git代码\frontlinux\LFtid1056\lib\libuv-v1.51.0\include;
D:\Git代码\frontlinux\LFtid1056\pqdif;
D:\Git代码\frontlinux\LFtid1056\pqdif\include;
.;
./cloudfront/code;
./cloudfront/code/log4cplus;
./cloudfront/code/log4cplus/include;
./lib/libuv-v1.51.0/include;
./pqdif;
./pqdif/include;
%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
</ClCompile>
<Link>
<AdditionalDependencies>/root/projects/LFtid1056/pqdif/lib/libpqdiflib.a;/root/projects/LFtid1056/pqdif/lib/libz.a;%(AdditionalDependencies)</AdditionalDependencies>
<AdditionalOptions>-Wl,-rpath=/root/projects/LFtid1056/cloudfront/lib -Wl,--start-group /root/projects/LFtid1056/pqdif/lib/libpqdiflib.a /root/projects/LFtid1056/pqdif/lib/libz.a -Wl,--end-group %(AdditionalOptions)</AdditionalOptions>
<AdditionalLibraryDirectories>/root/projects/LFtid1056/pqdif/lib</AdditionalLibraryDirectories>
</Link>
</ItemDefinitionGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets" />
</Project>

View File

@@ -26,6 +26,14 @@
<ClCompile Include="cloudfront\code\worker.cpp">
<Filter>cloudfront\code</Filter>
</ClCompile>
<ClCompile Include="pqdif\PQDIF.cpp">
<Filter>pqdif</Filter>
</ClCompile>
<ClCompile Include="pqdif\include\cjson.c">
<Filter>pqdif\include</Filter>
</ClCompile>
<ClCompile Include="pqdif_thread_processor.cpp" />
<ClCompile Include="pqdif_semantic_ids.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="client2.h" />
@@ -559,6 +567,116 @@
<ClInclude Include="cloudfront\code\log4cplus\thread\impl\tls.h">
<Filter>cloudfront\code\log4cplus\thread\impl</Filter>
</ClInclude>
<ClInclude Include="pqdif\PQDIF.h">
<Filter>pqdif</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\cjson.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\el_base.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\el_coll.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\el_scal.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\el_vect.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pcn_base.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pcn_flat.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqbytearray.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqdfacty.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\PQDIF_classes.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqdif_custom_1.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqdif_custom_2.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqdif_id.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqdif_lg.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqdif_ph.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqdinfo.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqdsupport.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\pqptrarray.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\proc_bas.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\proc_not.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\proc_zlib.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\rec_base.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\rec_container.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\rec_datasource.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\rec_general.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\rec_observ.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\rec_settings.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\ser_alloc.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\ser_cont_el.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\ser_iter_el.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\str_base.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\str_chnk.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\str_flat.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\zconf.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif\include\zlib.h">
<Filter>pqdif\include</Filter>
</ClInclude>
<ClInclude Include="pqdif_thread_processor.h" />
<ClInclude Include="pqdif_semantic_ids.h" />
</ItemGroup>
<ItemGroup>
<Filter Include="cloudfront">
@@ -633,6 +751,15 @@
<Filter Include="cloudfront\lib">
<UniqueIdentifier>{ca2cfaa3-ac76-42f8-a17f-67b4f693b719}</UniqueIdentifier>
</Filter>
<Filter Include="pqdif">
<UniqueIdentifier>{d602780e-e7fa-4253-b532-afd407583f88}</UniqueIdentifier>
</Filter>
<Filter Include="pqdif\include">
<UniqueIdentifier>{0e3fb7c4-4107-4518-b2ed-857f8c659fa0}</UniqueIdentifier>
</Filter>
<Filter Include="pqdif\lib">
<UniqueIdentifier>{721d48b7-af7b-4e48-84d2-21220c6534c3}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<None Include="cloudfront\code\curl\Makefile">
@@ -714,5 +841,11 @@
<Filter>cloudfront\lib</Filter>
</Library>
<Library Include="libuv.a" />
<Library Include="pqdif\lib\libpqdiflib.a">
<Filter>pqdif\lib</Filter>
</Library>
<Library Include="pqdif\lib\libz.a">
<Filter>pqdif\lib</Filter>
</Library>
</ItemGroup>
</Project>

View File

@@ -487,6 +487,133 @@ std::vector<unsigned char> generate_getfilemenu_message(const std::string& filed
return GetMsg(dataBuf, static_cast<unsigned char>(MsgRequestType::Request_FileDir));
}
/**
* @brief <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>
* @param data <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param sendCount <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>
* @param count <20><>֡<EFBFBD><D6A1>
* @param fileSize <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>ܴ<EFBFBD>С
* @param crc CRCУ<43><D0A3>ֵ
* @param filedir <20><><EFBFBD><EFBFBD>ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_sendfile_message(const std::vector<unsigned char>& data,
std::uint32_t sendCount,
std::uint32_t count,
std::uint32_t fileSize,
std::uint16_t crc,
const std::string& filedir) {
// <20><><EFBFBD><EFBFBD> 17+128 <20>ֽ<EFBFBD>ͷ<EFBFBD><CDB7> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
std::vector<unsigned char> DataBuf(17 + 128 + data.size(), 0x00);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嵽17+128<32>ֽ<EFBFBD>ͷ<EFBFBD><CDB7>֮<EFBFBD><D6AE>
std::copy(data.begin(), data.end(), DataBuf.begin() + 17 + 128);
DataBuf[0] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[1] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[2] = 0x00; // <20><><EFBFBD><EFBFBD>
// 4<>ֽڵ<D6BD>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>
DataBuf[3] = static_cast<unsigned char>(((sendCount + 1) >> 24) & 0xFF);
DataBuf[4] = static_cast<unsigned char>(((sendCount + 1) >> 16) & 0xFF);
DataBuf[5] = static_cast<unsigned char>(((sendCount + 1) >> 8) & 0xFF);
DataBuf[6] = static_cast<unsigned char>((sendCount + 1) & 0xFF);
// 4<>ֽ<EFBFBD><D6BD><EFBFBD>֡<EFBFBD><D6A1>
DataBuf[7] = static_cast<unsigned char>((count >> 24) & 0xFF);
DataBuf[8] = static_cast<unsigned char>((count >> 16) & 0xFF);
DataBuf[9] = static_cast<unsigned char>((count >> 8) & 0xFF);
DataBuf[10] = static_cast<unsigned char>(count & 0xFF);
// 4<>ֽ<EFBFBD><D6BD>ܴ<EFBFBD>С
DataBuf[11] = static_cast<unsigned char>((fileSize >> 24) & 0xFF);
DataBuf[12] = static_cast<unsigned char>((fileSize >> 16) & 0xFF);
DataBuf[13] = static_cast<unsigned char>((fileSize >> 8) & 0xFF);
DataBuf[14] = static_cast<unsigned char>(fileSize & 0xFF);
// 2<>ֽ<EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD>
DataBuf[15] = static_cast<unsigned char>((crc >> 8) & 0xFF);
DataBuf[16] = static_cast<unsigned char>(crc & 0xFF);
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>17<31><37>ʼ<EFBFBD><CABC>
size_t copyLen = std::min(filedir.size(), static_cast<size_t>(128));
if (copyLen > 0) {
memcpy(DataBuf.data() + 17, filedir.c_str(), copyLen);
}
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>8<EFBFBD><38>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_File_Send));
}
/**
* @brief <20>ļ<EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param filedir ɾ<><C9BE><EFBFBD>ļ<EFBFBD>ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_deletefile_message(const std::string& filedir) {
// <20><><EFBFBD><EFBFBD> 3 <20>ֽ<EFBFBD>ͷ<EFBFBD><CDB7> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
std::vector<unsigned char> DataBuf(3 + 128, 0x00);
DataBuf[0] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[1] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[2] = 0x00; // <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>3<EFBFBD><33>ʼ<EFBFBD><CABC>
size_t copyLen = std::min(filedir.size(), static_cast<size_t>(128));
if (copyLen > 0) {
memcpy(DataBuf.data() + 3, filedir.c_str(), copyLen);
}
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>9<EFBFBD><39>Ӧɾ<D3A6><C9BE><EFBFBD>ļ<EFBFBD>
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_File_Del));
}
/**
* @brief <20>ļ<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param filedir Ŀ¼ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_setmenu_message(const std::string& filedir) {
// <20><><EFBFBD><EFBFBD> 3 <20>ֽ<EFBFBD>ͷ<EFBFBD><CDB7> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
std::vector<unsigned char> DataBuf(3 + 128, 0x00);
DataBuf[0] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[1] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[2] = 0x00; // <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>3<EFBFBD><33>ʼ<EFBFBD><CABC>
size_t copyLen = std::min(filedir.size(), static_cast<size_t>(128));
if (copyLen > 0) {
memcpy(DataBuf.data() + 3, filedir.c_str(), copyLen);
}
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>11<31><31>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>Ŀ¼
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Menu_Set));
}
/**
* @brief <20>ļ<EFBFBD>Ŀ¼ɾ<C2BC><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param filedir Ŀ¼ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_delmenu_message(const std::string& filedir) {
// <20><><EFBFBD><EFBFBD> 3 <20>ֽ<EFBFBD>ͷ<EFBFBD><CDB7> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
std::vector<unsigned char> DataBuf(3 + 128, 0x00);
DataBuf[0] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[1] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[2] = 0x00; // <20><><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB><EFBFBD><EFBFBD>3<EFBFBD><33>ʼ<EFBFBD><CABC>
size_t copyLen = std::min(filedir.size(), static_cast<size_t>(128));
if (copyLen > 0) {
memcpy(DataBuf.data() + 3, filedir.c_str(), copyLen);
}
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>12<31><32>Ӧɾ<D3A6><C9BE>Ŀ¼
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Menu_Del));
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::vector<unsigned char> generate_requestFixValue_message(unsigned char nCpuNo) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -658,13 +785,103 @@ std::vector<unsigned char> generate_machineversion_message()
// <20><><EFBFBD><EFBFBD>10<31>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
std::vector<unsigned char> DataBuf(10, 0x00);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33>ֵΪ1<EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD><EFBFBD><EFBFBD>ֽڣ<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33>ֵΪ2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>4<EFBFBD><EFBFBD><EFBFBD>ֽڣ<EFBFBD>
DataBuf[3] = 0x02;
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>14<31><34>Ӧװ<D3A6><D7B0>״̬<D7B4><CCAC>ȡ
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Read_RunningInformation));
}
/**
* @brief <20><><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_preupgrade_message()
{
// <20><><EFBFBD><EFBFBD>10<31>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
std::vector<unsigned char> DataBuf(10, 0x00);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>3<EFBFBD><33>ֵΪ4<CEAA><34><EFBFBD><EFBFBD>4<EFBFBD><34><EFBFBD>ֽڣ<D6BD>
DataBuf[3] = 0x04;
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>14<31><34>Ӧװ<D3A6><D7B0>״̬<D7B4><CCAC>ȡ
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Read_RunningInformation));
}
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
* @param data <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param updateCount <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>
* @param updateSize <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>ܴ<EFBFBD>С
* @param count <20><>֡<EFBFBD><D6A1>
* @param crc CRCУ<43><D0A3>ֵ
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_upgrade_start_message(const std::vector<unsigned char>& data,
std::uint32_t updateCount,
std::uint32_t updateSize,
std::uint32_t count,
std::uint32_t crc)
{
// <20><><EFBFBD><EFBFBD>44<34>ֽ<EFBFBD>ͷ<EFBFBD><CDB7> + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
std::vector<unsigned char> DataBuf(44 + data.size(), 0x00);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>嵽44<34>ֽ<EFBFBD>ͷ<EFBFBD><CDB7>֮<EFBFBD><D6AE>
std::copy(data.begin(), data.end(), DataBuf.begin() + 44);
DataBuf[0] = 0x00; // У<>ʽ 0-crcУ<63><D0A3> 1-md5У<35><D0A3>
DataBuf[1] = 0x00; // <20><><EFBFBD><EFBFBD>
DataBuf[2] = 0x00; // <20><><EFBFBD><EFBFBD>
// 4<>ֽڵ<D6BD>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>
DataBuf[3] = static_cast<unsigned char>(((updateCount + 1) >> 24) & 0xFF);
DataBuf[4] = static_cast<unsigned char>(((updateCount + 1) >> 16) & 0xFF);
DataBuf[5] = static_cast<unsigned char>(((updateCount + 1) >> 8) & 0xFF);
DataBuf[6] = static_cast<unsigned char>((updateCount + 1) & 0xFF);
// 4<>ֽ<EFBFBD><D6BD><EFBFBD>֡<EFBFBD><D6A1>
DataBuf[7] = static_cast<unsigned char>((count >> 24) & 0xFF);
DataBuf[8] = static_cast<unsigned char>((count >> 16) & 0xFF);
DataBuf[9] = static_cast<unsigned char>((count >> 8) & 0xFF);
DataBuf[10] = static_cast<unsigned char>(count & 0xFF);
// 4<>ֽ<EFBFBD><D6BD>ܴ<EFBFBD>С
DataBuf[11] = static_cast<unsigned char>((updateSize >> 24) & 0xFF);
DataBuf[12] = static_cast<unsigned char>((updateSize >> 16) & 0xFF);
DataBuf[13] = static_cast<unsigned char>((updateSize >> 8) & 0xFF);
DataBuf[14] = static_cast<unsigned char>(updateSize & 0xFF);
// 4<>ֽ<EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD>
DataBuf[15] = static_cast<unsigned char>((crc >> 24) & 0xFF);
DataBuf[16] = static_cast<unsigned char>((crc >> 16) & 0xFF);
DataBuf[17] = static_cast<unsigned char>((crc >> 8) & 0xFF);
DataBuf[18] = static_cast<unsigned char>(crc & 0xFF);
DataBuf[19] = 0x00; // ѹ<><D1B9><EFBFBD><EFBFBD>ʽ <20><><EFBFBD><EFBFBD>
// DataBuf[20]~DataBuf[27] Ϊ0<CEAA><30>ѹǰ<D1B9><C7B0>С/ѹǰУ<C7B0><EFBFBD><E9B1B8>
// DataBuf[28]~DataBuf[43] Ϊ0<CEAA><30>16<31>ֽ<EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// vector <20><>ʼ<EFBFBD><CABC>ʱ<EFBFBD>Ѿ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD>0<EFBFBD><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>ֵ
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>38<33><38>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Upgrade));
}
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_upgrade_end_message()
{
// <20><><EFBFBD><EFBFBD>3<EFBFBD>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>Ϊ0
std::vector<unsigned char> DataBuf(3, 0x00);
DataBuf[0] = 0x55;//<2F><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
// <20><><EFBFBD><EFBFBD>ͨ<EFBFBD>ñ<EFBFBD><C3B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɺ<EFBFBD><C9BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>38<33><38>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Upgrade));
}
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD>ö<EFBFBD>ʱ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>
* @param time <20>·<EFBFBD><C2B7>Ķ<EFBFBD>ʱʱ<CAB1><CAB1> (tmֵ)
@@ -766,3 +983,33 @@ std::vector<uint8_t> generate_recallevent_message(const std::tm& Time1, const st
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>GetMsg<73><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>0x0D(<28>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD><EFBFBD>)
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Read_Event));
}
/**
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_requestHeartBeat_message() {
// <20><><EFBFBD><EFBFBD>3<EFBFBD>ֽڻ<D6BD><DABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
std::vector<unsigned char> DataBuf(3, 0x00);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_HeartBeat));
}
/**
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEB1A8>
* @param type <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1-װ<>ø<EFBFBD>λ<EFBFBD><CEBB>2-<2D><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>3-<2D><><EFBFBD><EFBFBD>200ms<6D><73><EFBFBD>ݼ<EFBFBD>¼<EFBFBD><C2BC>4-<2D><><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>¼
* @param ctrlflag <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3> <20>״δ<D7B4><CEB4><EFBFBD>0 <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD> 0x01ִ<31><D6B4> 0x02ȡ<32><C8A1>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_control_message(uint8_t type, uint8_t ctrlflag) {
// <20><><EFBFBD><EFBFBD>3<EFBFBD>ֽڻ<D6BD><DABB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
std::vector<unsigned char> DataBuf(3, 0x00);
DataBuf[0] = type; // 1-װ<>ø<EFBFBD>λ<EFBFBD><CEBB>2-<2D><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>3-<2D><><EFBFBD><EFBFBD>200ms<6D><73><EFBFBD>ݼ<EFBFBD>¼<EFBFBD><C2BC>4-<2D><><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>¼
DataBuf[1] = ctrlflag; // 0x01ִ<31><D6B4> 0x02ȡ<32><C8A1>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
return GetMsg(DataBuf, static_cast<unsigned char>(MsgRequestType::Request_Ctrl));
}

View File

@@ -18,6 +18,8 @@ float ShorToFloat1000(short num);
float ShorToFloat10000(short num);
// <20><><EFBFBD>ͱ<EFBFBD><CDB1>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>
enum class MsgRequestType : unsigned char {
//ѯ<><D1AF>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Request_HeartBeat = 0x01,
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
Request_StatTime = 0x8b,
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -26,6 +28,14 @@ enum class MsgRequestType : unsigned char {
Request_New_3S = 0x04,
//<2F><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>ļ<EFBFBD>
Request_File_Download = 0x07,
//<2F>ϴ<EFBFBD>װ<EFBFBD><D7B0><EFBFBD>ļ<EFBFBD>
Request_File_Send = 0x08,
//ɾ<><C9BE>װ<EFBFBD><D7B0><EFBFBD>ļ<EFBFBD>
Request_File_Del = 0x09,
//Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD>
Request_Menu_Set = 0x0b,
//Ŀ¼ɾ<C2BC><C9BE>
Request_Menu_Del = 0x0c,
//ѯ<><D1AF><EFBFBD>ļ<EFBFBD>Ŀ¼
Request_FileDir = 0x02,
//ѯ<><D1AF>װ<EFBFBD>ö<EFBFBD>ֵ
@@ -45,10 +55,16 @@ enum class MsgRequestType : unsigned char {
//<2F><><EFBFBD><EFBFBD>װ<EFBFBD>ö<EFBFBD>ʱ
Request_RightTime = 0x86,
//<2F><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>־
Request_Read_Event = 0x0D
Request_Read_Event = 0x0D,
//ִ<>п<EFBFBD><D0BF><EFBFBD><EFBFBD>¼<EFBFBD>
Request_Ctrl = 0x0A,
//ִ<><D6B4>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Request_Upgrade = 0x26
};
// <20><><EFBFBD>ձ<EFBFBD><D5B1>Ĺ<EFBFBD><C4B9><EFBFBD><EFBFBD><EFBFBD>ö<EFBFBD><C3B6>
enum class MsgResponseType : unsigned char {
//ѯ<><D1AF>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
Response_HeartBeat = 0x81,
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
Response_StatTime = 0x27,
//ѯ<><D1AF>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -61,6 +77,8 @@ enum class MsgResponseType : unsigned char {
Response_ActiveSOEInfo = 0x17,
//<2F><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>ļ<EFBFBD>
Response_File_Download = 0x87,
//<2F>ϴ<EFBFBD>װ<EFBFBD><D7B0><EFBFBD>ļ<EFBFBD> ֡<><D6A1><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD>Ĭ<EFBFBD><C4AC>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡<D2BB>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>һ֡<D2BB><D6A1>ȫ
Response_File_Send = 0x88,
//ѯ<><D1AF><EFBFBD>ļ<EFBFBD>Ŀ¼
Response_FileDir = 0x82,
//ѯ<><D1AF>װ<EFBFBD>ö<EFBFBD>ֵ
@@ -81,6 +99,10 @@ enum class MsgResponseType : unsigned char {
Response_RightTime = 0x86,
//<2F><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>־
Response_Read_Event = 0x8D,
//ִ<>п<EFBFBD><D0BF><EFBFBD><EFBFBD>¼<EFBFBD>Ӧ<EFBFBD><D3A6>
Response_Ctrl = 0x8a,
//װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>40/41Ĭ<31><C4AC>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ִ<EFBFBD>кͽ<D0BA><CDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ר<EFBFBD><D7A8>A6<41><36><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>
Response_Upgrade = 0xA6,
//Ĭ<>Ͽ϶<CFBF>Ӧ<EFBFBD><D3A6>
Response_NewACK = 0x40,
//Ĭ<>Ϸ<EFBFBD><CFB7><EFBFBD>Ӧ<EFBFBD><D3A6>
@@ -2369,6 +2391,40 @@ std::vector<unsigned char> generate_realstat_message(unsigned char nCpuNo, unsig
std::vector<unsigned char> generate_downloadfile_message(int frameIndex, const std::string& fileName);
//<2F>ļ<EFBFBD>Ŀ¼<C4BF><C2BC>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ȡ<EFBFBD><C8A1><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
std::vector<unsigned char> generate_getfilemenu_message(const std::string& filedir);
/**
* @brief <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>
* @param data <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param sendCount <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>
* @param count <20><>֡<EFBFBD><D6A1>
* @param fileSize <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>ܴ<EFBFBD>С
* @param crc CRCУ<43><D0A3>ֵ
* @param filedir <20><><EFBFBD><EFBFBD>ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_sendfile_message(const std::vector<unsigned char>& data,
std::uint32_t sendCount,
std::uint32_t count,
std::uint32_t fileSize,
std::uint16_t crc,
const std::string& filedir);
/**
* @brief <20>ļ<EFBFBD>ɾ<EFBFBD><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param filedir ɾ<><C9BE><EFBFBD>ļ<EFBFBD>ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_deletefile_message(const std::string& filedir);
/**
* @brief <20>ļ<EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param filedir Ŀ¼ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_setmenu_message(const std::string& filedir);
/**
* @brief <20>ļ<EFBFBD>Ŀ¼ɾ<C2BC><C9BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param filedir Ŀ¼ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_delmenu_message(const std::string& filedir);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::vector<unsigned char> generate_requestFixValue_message(unsigned char nCpuNo);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -2403,6 +2459,30 @@ std::vector<unsigned char> generate_machinestatus_message();
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_machineversion_message();
/**
* @brief <20><><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_preupgrade_message();
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
* @param data <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param updateCount <20><>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>
* @param updateSize <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC>ܴ<EFBFBD>С
* @param count <20><>֡<EFBFBD><D6A1>
* @param crc CRCУ<43><D0A3>ֵ
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_upgrade_start_message(const std::vector<unsigned char>& data,
std::uint32_t updateCount,
std::uint32_t updateSize,
std::uint32_t count,
std::uint32_t crc);
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͽ<EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_upgrade_end_message();
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD>ö<EFBFBD>ʱ<EFBFBD>ı<EFBFBD><C4B1><EFBFBD>
* @param time <20>·<EFBFBD><C2B7>Ķ<EFBFBD>ʱʱ<CAB1><CAB1> (tmֵ)
@@ -2418,3 +2498,15 @@ std::vector<uint8_t> generate_righttime_message(const std::tm& time);
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<uint8_t> generate_recallevent_message(const std::tm& Time1, const std::tm& Time2, uint8_t eventType = 2, uint8_t monitorPoint = 1);
/**
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_requestHeartBeat_message();
/**
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEB1A8>
* @param type <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1-װ<>ø<EFBFBD>λ<EFBFBD><CEBB>2-<2D><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>3-<2D><><EFBFBD><EFBFBD>200ms<6D><73><EFBFBD>ݼ<EFBFBD>¼<EFBFBD><C2BC>4-<2D><><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>¼
* @param ctrlflag <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3> <20>״δ<D7B4><CEB4><EFBFBD>0 <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD> 0x01ִ<31><D6B4> 0x02ȡ<32><C8A1>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
std::vector<unsigned char> generate_control_message(uint8_t type, uint8_t ctrlflag);

View File

@@ -19,7 +19,11 @@ $SRC_DIR/tinyxml2.cpp \
./client2.cpp \
./dealMsg.cpp \
./main_thread.cpp \
./PQSMsg.cpp "
./PQSMsg.cpp \
./pqdif/PQDIF.cpp \
./pqdif_semantic_ids.cpp \
./pqdif_thread_processor.cpp \
./pqdif/include/cjson.c"
INCLUDE_DIRS="-I$SRC_DIR \
-I$SRC_DIR/nlohmann \
@@ -28,9 +32,11 @@ INCLUDE_DIRS="-I$SRC_DIR \
-I$SRC_DIR/rocketmq \
-I$SRC_DIR \
-I./lib/libuv-v1.51.0/include \
-I./pqdif \
-I./pqdif/include \
-I. "
LIB_DIRS="-L$LIB_DIR -L/usr/lib64 -L/usr/local/lib"
LIB_DIRS="-L$LIB_DIR -L./pqdif/lib -L/usr/lib64 -L/usr/local/lib"
LIBS="./cloudfront/lib/libcurl.so \
./cloudfront/lib/libssl.so \
@@ -40,6 +46,10 @@ LIBS="./cloudfront/lib/libcurl.so \
-lstdc++fs \
-lz \
./libuv.a \
-Wl,--start-group \
./pqdif/lib/libpqdiflib.a \
./pqdif/lib/libz.a \
-Wl,--end-group \
-pthread"
# 如果有静态 rocketmq 库就加上

View File

@@ -23,6 +23,71 @@ static uv_loop_t* global_loop = nullptr;
static uv_timer_t monitor_timer;
extern SafeMessageQueue message_queue;
// 生成与 C# CreateNormalCrc32Table 完全对应的表
static std::array<uint32_t, 256> CreateNormalCrc32Table_Char(uint32_t poly)
{
std::array<uint32_t, 256> table{};
for (int i = 0; i < 256; ++i)
{
uint32_t data = static_cast<uint32_t>(i) << 24;
for (int j = 0; j < 8; ++j)
{
bool flag = (data & 0x80000000u) == 0x80000000u;
if (flag)
{
data = (data << 1) ^ poly;
}
else
{
data <<= 1;
}
}
table[i] = data;
}
return table;
}
// 与 C# CalcNoemalCrc32 完全对应
static uint32_t CalcNormalCrc32_Char(const std::vector<unsigned char>& bytes,
uint32_t poly = 0x04C11DB7u)
{
static const std::array<uint32_t, 256> table = CreateNormalCrc32Table_Char(poly);
uint32_t crc = 0xFFFFFFFFu;
for (size_t i = 0; i < bytes.size(); ++i)
{
crc = (crc << 8) ^ table[((crc >> 24) & 0xFFu) ^ bytes[i]];
}
return crc;
}
// 与 C# Crc_16_new 完全对应Modbus CRC16
static uint16_t CalcCrc16_Char(const std::vector<unsigned char>& bytes)
{
uint16_t crc = 0xFFFF;
for (size_t i = 0; i < bytes.size(); ++i)
{
crc = static_cast<uint16_t>(crc ^ static_cast<uint16_t>(bytes[i]));
for (int j = 0; j < 8; ++j)
{
if ((crc & 0x0001) == 0x0001)
{
crc = static_cast<uint16_t>((crc >> 1) ^ 0xA001);
}
else
{
crc = static_cast<uint16_t>(crc >> 1);
}
}
}
return crc;
}
// ClientContext 实现
ClientContext::ClientContext(uv_loop_t* loop, const DeviceInfo& device, int index)
: loop(loop), state(ConnectionState::DISCONNECTED),
@@ -348,6 +413,254 @@ void ClientContext::clear_float_cache() {
std::lock_guard<std::mutex> lock(float_cache_mutex_);
point_float_cache_.clear();
}
//升级管理相关函数
/**
* @brief 程序切片函数
* @param file 升级程序文件
* @param frame_index 要发送的帧序号
* @param frame_payload_size 单帧数据长
* @return 切片数据
*/
static std::vector<unsigned char> slice_frame_data(const std::vector<unsigned char>& file,
uint32_t frame_index,
uint32_t frame_payload_size)
{
const uint64_t offset = static_cast<uint64_t>(frame_index) * frame_payload_size;
if (offset >= file.size()) {
return {};
}
const uint64_t remain = file.size() - offset;
const uint64_t copy_len = std::min<uint64_t>(remain, frame_payload_size);
return std::vector<unsigned char>(
file.begin() + static_cast<std::ptrdiff_t>(offset),
file.begin() + static_cast<std::ptrdiff_t>(offset + copy_len));
}
/**
* @brief 装置升级参数初始化
* @param file 升级程序文件
* @param frame_payload_size 单帧数据长
* @return 是否需要升级
*/
bool ClientContext::prepare_upgrade_task(const std::vector<unsigned char>& file, uint32_t frame_payload_size)
{
if (file.empty() || frame_payload_size == 0) {
return false;
}
std::lock_guard<std::mutex> lock(upgrade_mutex_);
upgrade_task_.file_data = file;
upgrade_task_.file_size = static_cast<uint32_t>(file.size());
upgrade_task_.file_crc = CalcNormalCrc32_Char(file, 0x04C11DB7u);
upgrade_task_.frame_payload_size = frame_payload_size;
upgrade_task_.total_frames =
static_cast<uint32_t>((file.size() + frame_payload_size - 1) / frame_payload_size);
upgrade_task_.next_frame_index = 0;
upgrade_task_.active = (upgrade_task_.total_frames > 0);
return upgrade_task_.active;
}
/**
* @brief 生成升级传输的下一帧报文
* @param out_packet 升级报文
* @param finished 是否结束
* @return 是否继续
*/
bool ClientContext::build_next_upgrade_packet(std::vector<unsigned char>& out_packet, bool& finished)
{
std::lock_guard<std::mutex> lock(upgrade_mutex_);
finished = false;
out_packet.clear();
if (!upgrade_task_.active) {
return false;
}
if (upgrade_task_.next_frame_index >= upgrade_task_.total_frames) {
finished = true;
upgrade_task_.active = false;
return false;
}
std::vector<unsigned char> frame_data =
slice_frame_data(upgrade_task_.file_data,
upgrade_task_.next_frame_index,
upgrade_task_.frame_payload_size);
if (frame_data.empty()) {
upgrade_task_.active = false;
return false;
}
out_packet = generate_upgrade_start_message(
frame_data,
upgrade_task_.next_frame_index, // 0-based内部会 +1
upgrade_task_.file_size,
upgrade_task_.total_frames,
upgrade_task_.file_crc
);
++upgrade_task_.next_frame_index;
if (upgrade_task_.next_frame_index >= upgrade_task_.total_frames) {
finished = true;
}
return true;
}
/**
* @brief 获取当前升级的当前帧和总帧数
* @param current_frame_index 当前帧
* @param total_frames 总帧数
* @return 是否正常
*/
bool ClientContext::get_upgrade_progress(uint32_t& current_frame_index, uint32_t& total_frames) const
{
std::lock_guard<std::mutex> lock(upgrade_mutex_);
if (!upgrade_task_.active) {
current_frame_index = 0;
total_frames = 0;
return false;
}
current_frame_index = upgrade_task_.next_frame_index;
total_frames = upgrade_task_.total_frames;
return true;
}
void ClientContext::clear_upgrade_task()
{
std::lock_guard<std::mutex> lock(upgrade_mutex_);
upgrade_task_ = UpgradeTask{};
}
bool ClientContext::has_active_upgrade_task() const
{
std::lock_guard<std::mutex> lock(upgrade_mutex_);
return upgrade_task_.active;
}
/**
* @brief 文件上送参数初始化
* @param file 上送文件内容
* @param frame_payload_size 单帧数据长
* @param dest_file_path 装置端目标全路径
* @return 是否初始化成功
*/
bool ClientContext::prepare_send_file_task(const std::vector<unsigned char>& file,
uint32_t frame_payload_size,
const std::string& dest_file_path)
{
if (file.empty() || frame_payload_size == 0 || dest_file_path.empty()) {
return false;
}
std::lock_guard<std::mutex> lock(send_file_mutex_);
send_file_task_.file_data = file;
send_file_task_.file_size = static_cast<uint32_t>(file.size());
send_file_task_.file_crc = CalcCrc16_Char(file);
send_file_task_.frame_payload_size = frame_payload_size;
send_file_task_.total_frames =
static_cast<uint32_t>((file.size() + frame_payload_size - 1) / frame_payload_size);
send_file_task_.next_frame_index = 0;
send_file_task_.dest_file_path = dest_file_path;
send_file_task_.active = (send_file_task_.total_frames > 0);
return send_file_task_.active;
}
/**
* @brief 生成文件上送的下一帧报文
* @param out_packet 上送报文
* @param finished 是否结束
* @return 是否继续
*/
bool ClientContext::build_next_send_file_packet(std::vector<unsigned char>& out_packet, bool& finished)
{
std::lock_guard<std::mutex> lock(send_file_mutex_);
finished = false;
out_packet.clear();
if (!send_file_task_.active) {
return false;
}
if (send_file_task_.next_frame_index >= send_file_task_.total_frames) {
finished = true;
send_file_task_.active = false;
return false;
}
std::vector<unsigned char> frame_data =
slice_frame_data(send_file_task_.file_data,
send_file_task_.next_frame_index,
send_file_task_.frame_payload_size);
if (frame_data.empty()) {
send_file_task_.active = false;
return false;
}
out_packet = generate_sendfile_message(
frame_data,
send_file_task_.next_frame_index, // 0-based函数内部会 +1
send_file_task_.total_frames,
send_file_task_.file_size,
send_file_task_.file_crc,
send_file_task_.dest_file_path
);
++send_file_task_.next_frame_index;
if (send_file_task_.next_frame_index >= send_file_task_.total_frames) {
finished = true;
}
return true;
}
/**
* @brief 获取当前文件上送的当前帧和总帧数
* @param current_frame_index 当前帧
* @param total_frames 总帧数
* @return 是否正常
*/
bool ClientContext::get_send_file_progress(uint32_t& current_frame_index, uint32_t& total_frames) const
{
std::lock_guard<std::mutex> lock(send_file_mutex_);
if (!send_file_task_.active) {
current_frame_index = 0;
total_frames = 0;
return false;
}
current_frame_index = send_file_task_.next_frame_index;
total_frames = send_file_task_.total_frames;
return true;
}
void ClientContext::clear_send_file_task()
{
std::lock_guard<std::mutex> lock(send_file_mutex_);
send_file_task_ = SendFileTask{};
}
bool ClientContext::has_active_send_file_task() const
{
std::lock_guard<std::mutex> lock(send_file_mutex_);
return send_file_task_.active;
}
// 版本比较函数的辅助函数:分割字符串并转换为整数向量
std::vector<int> splitVersionString(const std::string& versionStr) {
std::vector<int> segments;
@@ -479,6 +792,17 @@ void on_timer(uv_timer_t* handle) {
auto sendbuff = generate_statequerytime_message();//组装询问统计数据时间报文
ctx->add_action(DeviceState::READING_STATS_TIME, sendbuff);//将该状态以及待发送报文存入队列
}
//30秒一次 执行询问装置心跳
now = uv_now(ctx->loop);
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->heartbeat_time >= 30000) {
//更新装置心跳最新发送时间
ctx->heartbeat_time = now;
auto sendbuff = generate_requestHeartBeat_message();//组装装置心跳报文
ctx->add_action(DeviceState::HEART_BEAT, sendbuff);//将该状态以及待发送报文存入队列
}
//一秒一次 执行实时数据询问 仅执行指定次数
now = uv_now(ctx->loop);
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->real_state_query_time_ >= 1000 && ctx->real_state_count > 0) {
@@ -489,6 +813,7 @@ void on_timer(uv_timer_t* handle) {
auto sendbuff = generate_realstat_message(static_cast<unsigned char>(ctx->real_point_id_), static_cast<unsigned char>(0x01), static_cast<unsigned char>(0x01));//组装询问实时数据报文
ctx->add_action(DeviceState::READING_REALSTAT, sendbuff);//将该状态以及待发送报文存入队列
}
//30分钟一次 读取装置运行信息
now = uv_now(ctx->loop);
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->read_runninginformationMsg >= 60000 * 30)
@@ -499,7 +824,8 @@ void on_timer(uv_timer_t* handle) {
auto sendbuff = generate_machinestatus_message();//组装读取装置运行信息报文
ctx->add_action(DeviceState::READING_RUNNINGINFORMATION_2, sendbuff);//将该状态以及待发送报文存入队列
}
//30分钟一次 启动装置对时 仅在台账开启对时且云协议版本大于1.5时开启对时 60000 * 30
//30分钟一次 启动装置对时 仅在台账开启对时且云协议版本大于等于1.5时开启对时 60000 * 30
now = uv_now(ctx->loop);
if (ctx->current_state_ == DeviceState::IDLE && now - ctx->right_time >= 60000 * 30 && ctx->device_info.righttime && isVersionGreaterOrEqual(ctx->dev_CloudProtocolVer,"V1.5"))
{
@@ -515,6 +841,7 @@ void on_timer(uv_timer_t* handle) {
//auto sendbuff = generate_machinestatus_message();//组装读取装置运行信息报文
//ctx->add_action(DeviceState::READING_RUNNINGINFORMATION_2, sendbuff);//将该状态以及待发送报文存入队列
}
//处理后续工作队列的工作 取出一个并执行
if (ctx->current_state_ == DeviceState::IDLE) {
ctx->process_next_action();
@@ -717,6 +1044,7 @@ void on_connect(uv_connect_t* req, int status) {
ctx->state = ConnectionState::CONNECTED;
ctx->reconnect_attempts = 0;
// 新增:初始化各个计时时间戳
ctx->heartbeat_time = uv_now(ctx->loop);//初始化心跳报文时间戳
ctx->last_state_query_time_ = uv_now(ctx->loop);//初始化统计数据时间戳
ctx->real_state_query_time_ = uv_now(ctx->loop);//初始化实时数据时间戳
ctx->read_runninginformationMsg = uv_now(ctx->loop);//初始化读取装置运行信息时间戳
@@ -982,12 +1310,14 @@ bool ClientManager::set_cloud_status(const std::string& identifier, int status)
connect_status_update(identifier, status);
std::cout << "[Device " << identifier
<< "] ****Cloud status: " << ctx->cloudstatus << " updated to: " << status << std::endl;
DIY_INFOLOG_CODE(identifier,1,LOG_CODE_COMM,"设备登录状态更新为在线");
}
else if (ctx->cloudstatus == 1 && status == 0) {
//设备从在线转换至离线,通知前台状态发生翻转
connect_status_update(identifier, status);
std::cout << "[Device " << identifier
<< "] ****Cloud status: " << ctx->cloudstatus << " updated to: " << status << std::endl;
DIY_INFOLOG_CODE(identifier,1,LOG_CODE_COMM,"设备登录状态更新为离线");
}
// 修改云前置登录状态
@@ -1463,6 +1793,108 @@ bool ClientManager::add_file_download_action_to_device(
return false; // 设备未找到
}
/**
* @brief 生成删除装置文件报文
* @param file_path 文件全路径
* @return 发送结果
*/
bool ClientManager::add_file_delete_action_to_device(
const std::string& identifier,
const std::string& file_path) {
std::lock_guard<std::mutex> lock(mutex_);
// 查找匹配的设备
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier)
{
// 生成文件删除请求报文
auto delMsg = generate_deletefile_message(file_path);
// 添加动作到队列 (状态: 删除指定文件)
ctx->add_action(DeviceState::DEL_FILE, delMsg);
// 如果当前空闲则立即执行
if (ctx->current_state_ == DeviceState::IDLE) {
ctx->process_next_action();
}
return true; // 成功添加
}
}
return false; // 设备未找到
}
/**
* @brief 生成创建目录报文
* @param file_path 文件全路径
* @return 发送结果
*/
bool ClientManager::add_menu_set_action_to_device(
const std::string& identifier,
const std::string& file_path) {
std::lock_guard<std::mutex> lock(mutex_);
// 查找匹配的设备
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier)
{
// 生成目录创建请求报文
auto delMsg = generate_setmenu_message(file_path);
// 添加动作到队列 (状态: 创建目录)
ctx->add_action(DeviceState::SEND_MENU, delMsg);
// 如果当前空闲则立即执行
if (ctx->current_state_ == DeviceState::IDLE) {
ctx->process_next_action();
}
return true; // 成功添加
}
}
return false; // 设备未找到
}
/**
* @brief 生成删除目录报文
* @param file_path 文件全路径
* @return 发送结果
*/
bool ClientManager::add_menu_del_action_to_device(
const std::string& identifier,
const std::string& file_path) {
std::lock_guard<std::mutex> lock(mutex_);
// 查找匹配的设备
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier)
{
// 生成目录删除请求报文
auto delMsg = generate_delmenu_message(file_path);
// 添加动作到队列 (状态: 删除目录)
ctx->add_action(DeviceState::DEL_MENU, delMsg);
// 如果当前空闲则立即执行
if (ctx->current_state_ == DeviceState::IDLE) {
ctx->process_next_action();
}
return true; // 成功添加
}
}
return false; // 设备未找到
}
//获取指定装置指定测点下的定值数据
bool ClientManager::get_fixedvalue_action_to_device(const std::string& identifier, ushort point_id) {
std::lock_guard<std::mutex> lock(mutex_);
@@ -1698,10 +2130,10 @@ bool ClientManager::read_devversion_action_to_device(const std::string& identifi
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier)
{
// 生成定值描述报文
// 生成版本配置报文
auto packet = generate_machineversion_message();
// 添加动作到队列 (状态: 读取文件目录)
// 添加动作到队列 (状态: 读取装置版本信息)
ctx->add_action(DeviceState::READING_DEVVERSION, packet);
// 如果当前空闲则立即执行
@@ -1715,6 +2147,285 @@ bool ClientManager::read_devversion_action_to_device(const std::string& identifi
return false; // 设备未找到
}
/**
* @brief 生成预升级校验报文
* @param path 预校验文件路径
* @return 发送结果
*/
bool ClientManager::set_preupgrade_action_to_device(const std::string& identifier, const std::string& path) {
std::lock_guard<std::mutex> lock(mutex_);
// 查找匹配的设备
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier)
{
//设置用于校验的预升级文件 校验采用默认生成的文件 暂时不使用
//ctx->set_preupgrade_filepath(path);
// 生成预升级报文
auto packet = generate_preupgrade_message();
// 添加动作到队列 (状态: 预升级校验)
ctx->add_action(DeviceState::SET_PREUPGRADE, packet);
// 如果当前空闲则立即执行
if (ctx->current_state_ == DeviceState::IDLE) {
ctx->process_next_action();
}
return true; // 成功添加
}
}
return false; // 设备未找到
}
/**
* @brief 装置升级动作 发送初始帧
* @param file 升级程序文件
* @param sin_length 上送单帧长度
* @return 发送结果
*/
bool ClientManager::send_upgrade_action_to_device(const std::string& identifier, const std::vector<unsigned char>& file,int sin_length) {
std::lock_guard<std::mutex> lock(mutex_);
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier) {
//此处计算文件总大小将参数程序文件分割成依照单帧长度的多组文件计算文件crc计算保存总帧数保存当前帧计数
//之后重新写一个ClientManager的函数用于将之前计算出的参数验证正常后依次自动生成报文并执行不要直接在这里执行因为后续会在别的地方调用防止需要一直获取所有参数再生成报文直接打包方便调用。
// 1. 先准备升级任务
if (!ctx->prepare_upgrade_task(file, static_cast<uint32_t>(sin_length))) {
return false;
}
// 2. 生成首帧升级报文
std::vector<unsigned char> first_packet;
bool finished = false;
if (!ctx->build_next_upgrade_packet(first_packet, finished) || first_packet.empty()) {
ctx->clear_upgrade_task();
return false;
}
// 添加动作到队列 (状态: 读取文件目录)
ctx->add_action(DeviceState::SET_UPGRADE, first_packet);
// 如果当前空闲则立即执行
if (ctx->current_state_ == DeviceState::IDLE) {
ctx->process_next_action();
}
return true; // 成功添加
}
}
return false;
}
/**
* @brief 装置升级动作 查询并生成下一帧报文
* @param identifier 装置标识device_id 或 mac
* @param current_frame_index 获取当前帧(0-based表示下一次要发送的帧号)
* @param total_frames 获取总帧数
* @param all_sent 是否全部发送完毕
* @param packet 输出的下一帧报文;若已发送完毕则为空
* @return 获取结果
*/
bool ClientManager::try_get_next_upgrade_packet_to_device(const std::string& identifier,
uint32_t& current_frame_index,
uint32_t& total_frames,
bool& all_sent,
std::vector<unsigned char>& packet)
{
current_frame_index = 0;
total_frames = 0;
all_sent = false;
packet.clear();
std::lock_guard<std::mutex> lock(mutex_);
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier)
{
// 先获取当前进度
if (!ctx->get_upgrade_progress(current_frame_index, total_frames)) {
return false; // 没有活动升级任务
}
// 如果当前帧号已经到总帧数,说明全部发送完毕
if (current_frame_index >= total_frames) {
all_sent = true;
return true;
}
// 还有帧未发送,则只生成下一帧报文,不在这里直接发送
bool finished = false;
if (!ctx->build_next_upgrade_packet(packet, finished)) {
packet.clear();
return false;
}
// build_next_upgrade_packet 之后next_frame_index 已经自增
// 这里再更新一次进度给外部
ctx->get_upgrade_progress(current_frame_index, total_frames);
if (current_frame_index >= total_frames) {
all_sent = true;
}
return true;
}
}
return false; // 未找到设备
}
/**
* @brief 文件上送动作 发送初始帧
* @param file 上送文件内容
* @param sin_length 上送单帧长度
* @param dest_file_path 装置端目标全路径
* @return 发送结果
*/
bool ClientManager::send_file_action_to_device(const std::string& identifier,
const std::vector<unsigned char>& file,
int sin_length,
const std::string& dest_file_path)
{
std::lock_guard<std::mutex> lock(mutex_);
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier) {
// 1. 先准备文件上送任务
if (!ctx->prepare_send_file_task(file,
static_cast<uint32_t>(sin_length),
dest_file_path)) {
return false;
}
// 2. 生成首帧上送报文
std::vector<unsigned char> first_packet;
bool finished = false;
if (!ctx->build_next_send_file_packet(first_packet, finished) ||
first_packet.empty()) {
ctx->clear_send_file_task();
return false;
}
// 3. 添加动作到队列
ctx->add_action(DeviceState::SEND_FILE, first_packet);
// 4. 如果当前空闲则立即执行
if (ctx->current_state_ == DeviceState::IDLE) {
ctx->process_next_action();
}
return true;
}
}
return false;
}
/**
* @brief 文件上送动作 查询并生成下一帧报文
* @param identifier 装置标识device_id 或 mac
* @param current_frame_index 获取当前帧(0-based表示下一次要发送的帧号)
* @param total_frames 获取总帧数
* @param all_sent 是否全部发送完毕
* @param packet 输出的下一帧报文;若已发送完毕则为空
* @return 获取结果
*/
bool ClientManager::try_get_next_send_file_packet_to_device(const std::string& identifier,
uint32_t& current_frame_index,
uint32_t& total_frames,
bool& all_sent,
std::vector<unsigned char>& packet)
{
current_frame_index = 0;
total_frames = 0;
all_sent = false;
packet.clear();
std::lock_guard<std::mutex> lock(mutex_);
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier)
{
// 先获取当前进度
if (!ctx->get_send_file_progress(current_frame_index, total_frames)) {
return false; // 没有活动上送任务
}
// 已经发完
if (current_frame_index >= total_frames) {
all_sent = true;
return true;
}
// 生成下一帧报文
bool finished = false;
if (!ctx->build_next_send_file_packet(packet, finished)) {
packet.clear();
return false;
}
// build_next_send_file_packet 之后next_frame_index 已自增
ctx->get_send_file_progress(current_frame_index, total_frames);
if (current_frame_index >= total_frames) {
all_sent = true;
}
return true;
}
}
return false;
}
/**
* @brief 生成装置控制命令报文
* @param type 命令类型 1-装置复位2-启动录波3-启动200ms数据记录4-启动3秒数据记录
* @param ctrlflag 命令校验 首次传入0x00 接收校验应答后 0x01执行 0x02取消
* @return 包含完整报文的字节向量
*/
bool ClientManager::set_ctrl_action_to_device(const std::string& identifier, uint8_t type, uint8_t ctrlflag) {
std::lock_guard<std::mutex> lock(mutex_);
// 查找匹配的设备
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier)
{
// 生成控制命令报文
auto packet = generate_control_message(type, ctrlflag);
// 添加动作到队列 (状态: 设置装置控制命令)
ctx->add_action(DeviceState::SET_CTRL, packet);
// 如果当前空闲则立即执行
if (ctx->current_state_ == DeviceState::IDLE) {
ctx->process_next_action();
}
return true; // 成功添加
}
}
return false; // 设备未找到
}
/**
* @brief 补招事件日志动作
* @param Time1 起始时间
@@ -1734,10 +2445,10 @@ bool ClientManager::read_eventlog_action_to_device(const std::string& identifier
ctx->device_info.mac == identifier)
{
ctx->event_lineNo = monitorPoint;
// 生成定值描述报文
// 生成补招报文
auto packet = generate_recallevent_message(Time1, Time2, eventType, monitorPoint);
// 添加动作到队列 (状态: 读取文件目录)
// 添加动作到队列 (状态: 补招事件)
ctx->add_action(DeviceState::READING_EVENTLOG, packet);
// 如果当前空闲则立即执行
@@ -1893,6 +2604,7 @@ bool ClientManager::update_current_filename(const std::string& identifier,
return false;
}
//获取当前正在下载的文件名
std::string ClientManager::get_current_filename(const std::string& identifier) {
std::lock_guard<std::mutex> lock(mutex_);
for (auto& pair : clients_) {
@@ -1904,3 +2616,16 @@ std::string ClientManager::get_current_filename(const std::string& identifier) {
}
return "";
}
//获取用于预校验的文件路径
std::string ClientManager::get_preupgrade_filepath(const std::string& identifier) {
std::lock_guard<std::mutex> lock(mutex_);
for (auto& pair : clients_) {
auto& ctx = pair.second;
if (ctx->device_info.device_id == identifier ||
ctx->device_info.mac == identifier) {
return ctx->get_preupgrade_filepath();
}
}
return "";
}

View File

@@ -10,6 +10,7 @@
#include <queue>
#include "dealMsg.h"
#include "PQSMsg.h"
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD>
struct PointInfo {
std::string point_id; // <20><><EFBFBD><EFBFBD>ID
@@ -44,11 +45,16 @@ enum class ConnectionState {
// <20><><EFBFBD>ӵ<EFBFBD>״̬ö<CCAC><C3B6>
enum class DeviceState {
IDLE, // <20><><EFBFBD><EFBFBD>״̬
HEART_BEAT, // װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
READING_STATS, // <20><>ȡͳ<C8A1><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
READING_STATS_TIME, // <20><>ȡͳ<C8A1><CDB3>ʱ<EFBFBD><CAB1>
READING_REALSTAT, // <20><>ȡʵʱ<CAB5><CAB1><EFBFBD><EFBFBD>
READING_EVENTFILE, // <20><>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
READING_FILEMENU, // <20><>ȡ<EFBFBD>ļ<EFBFBD>Ŀ¼
SEND_FILE, // <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
DEL_FILE, // <20>ļ<EFBFBD>ɾ<EFBFBD><C9BE>
SEND_MENU, // Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD>
DEL_MENU, // Ŀ¼ɾ<C2BC><C9BE>
READING_FILEDATA, // <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
READING_FIXEDVALUE, // <20><>ȡ<EFBFBD><C8A1><EFBFBD>㶨ֵ
READING_FIXEDVALUEDES, // <20><>ȡ<EFBFBD><C8A1><EFBFBD>㶨ֵ<E3B6A8><D6B5><EFBFBD><EFBFBD>
@@ -64,6 +70,9 @@ enum class DeviceState {
SET_RIGHTTIME_2, // <20><><EFBFBD><EFBFBD>װ<EFBFBD>ö<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
READING_EVENTLOG, // <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD>־
READING_STATSFILE, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
SET_CTRL, // <20><><EFBFBD><EFBFBD>װ<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
SET_PREUPGRADE, // װ<><D7B0>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>У<EFBFBD><D0A3>
SET_UPGRADE, // װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20>ɸ<EFBFBD><C9B8><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD>Ӹ<EFBFBD><D3B8><EFBFBD>״̬
CUSTOM_ACTION // <20>Զ<EFBFBD><D4B6><EFBFBD><E5B6AF>
};
@@ -83,6 +92,7 @@ public:
ConnectionState state;
int reconnect_attempts;
volatile bool shutdown;
uint64_t heartbeat_time = 0;// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD>
uint64_t last_state_query_time_ = 0; // ͳ<><CDB3><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD>
uint64_t real_state_query_time_ = 0; // ʵʱ<CAB5><CAB1><EFBFBD>ݼ<EFBFBD>ʱʱ<CAB1><CAB1><EFBFBD><EFBFBD>
std::atomic<int> real_state_count{ 0 };//ʵʱ<CAB5><CAB1><EFBFBD><EFBFBD><EFBFBD>շ<EFBFBD><D5B7><EFBFBD><EFBFBD><EFBFBD> ԭ<>Ӳ<EFBFBD><D3B2><EFBFBD><EFBFBD><EFBFBD>֤<EFBFBD>̰߳<DFB3>ȫ
@@ -141,6 +151,91 @@ public:
bool event_add_stat_packet(const std::vector<unsigned char>& packet, int current_packet, int total_packets);//<2F>¼<EFBFBD><C2BC><EFBFBD>־<EFBFBD><D6BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::vector<StatPacket> event_get_and_clear_stat_packets();//<2F>¼<EFBFBD><C2BC><EFBFBD>־ȡ<D6BE><C8A1><EFBFBD><EFBFBD><EFBFBD>л<EFBFBD><D0BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD>
void event_clear_stat_cache();//<2F>¼<EFBFBD><C2BC><EFBFBD>־<EFBFBD><D6BE><EFBFBD>ջ<EFBFBD><D5BB><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>--------------------------------------------------
struct UpgradeTask
{
std::vector<unsigned char> file_data; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
uint32_t file_size = 0; // <20>ļ<EFBFBD><C4BC>ܴ<EFBFBD>С
uint32_t file_crc = 0; // <20>ļ<EFBFBD>CRC32
uint32_t frame_payload_size = 0; // <20><>֡<EFBFBD><D6A1><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
uint32_t total_frames = 0; // <20><>֡<EFBFBD><D6A1>
uint32_t next_frame_index = 0; // <20><>һ<EFBFBD><D2BB>Ҫ<EFBFBD><D2AA><EFBFBD>͵<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>(0-based)
bool active = false; // <20><>ǰ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
mutable std::mutex upgrade_mutex_;
UpgradeTask upgrade_task_;
/**
* @brief װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
* @param file <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
* @param frame_payload_size <20><>֡<EFBFBD><D6A1><EFBFBD>ݳ<EFBFBD>
* @return <20>Ƿ<EFBFBD><C7B7><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD>
*/
bool prepare_upgrade_task(const std::vector<unsigned char>& file, uint32_t frame_payload_size);
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡<D2BB><D6A1><EFBFBD><EFBFBD>
* @param out_packet <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param finished <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
* @return <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
*/
bool build_next_upgrade_packet(std::vector<unsigned char>& out_packet, bool& finished);
void clear_upgrade_task();
bool has_active_upgrade_task() const;
/**
* @brief <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>
* @param current_frame_index <20><>ǰ֡
* @param total_frames <20><>֡<EFBFBD><D6A1>
* @return <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
*/
bool get_upgrade_progress(uint32_t& current_frame_index, uint32_t& total_frames) const;
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>--------------------------------------------------
// <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>--------------------------------------------------
struct SendFileTask
{
std::vector<unsigned char> file_data; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
uint32_t file_size = 0; // <20>ļ<EFBFBD><C4BC>ܴ<EFBFBD>С
uint16_t file_crc = 0; // <20>ļ<EFBFBD>CRC16
uint32_t frame_payload_size = 0; // <20><>֡<EFBFBD><D6A1><EFBFBD>ݳ<EFBFBD><DDB3><EFBFBD>
uint32_t total_frames = 0; // <20><>֡<EFBFBD><D6A1>
uint32_t next_frame_index = 0; // <20><>һ<EFBFBD><D2BB>Ҫ<EFBFBD><D2AA><EFBFBD>͵<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>(0-based)
std::string dest_file_path; // װ<>ö<EFBFBD>Ŀ<EFBFBD><C4BF>ȫ·<C8AB><C2B7>
bool active = false; // <20><>ǰ<EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
};
mutable std::mutex send_file_mutex_;
SendFileTask send_file_task_;
/**
* @brief <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>Ͳ<EFBFBD><CDB2><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
* @param file <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
* @param frame_payload_size <20><>֡<EFBFBD><D6A1><EFBFBD>ݳ<EFBFBD>
* @param dest_file_path װ<>ö<EFBFBD>Ŀ<EFBFBD><C4BF>ȫ·<C8AB><C2B7>
* @return <20>Ƿ<EFBFBD><C7B7><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD>ɹ<EFBFBD>
*/
bool prepare_send_file_task(const std::vector<unsigned char>& file,
uint32_t frame_payload_size,
const std::string& dest_file_path);
/**
* @brief <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>͵<EFBFBD><CDB5><EFBFBD>һ֡<D2BB><D6A1><EFBFBD><EFBFBD>
* @param out_packet <20><><EFBFBD>ͱ<EFBFBD><CDB1><EFBFBD>
* @param finished <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
* @return <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
*/
bool build_next_send_file_packet(std::vector<unsigned char>& out_packet, bool& finished);
void clear_send_file_task();
bool has_active_send_file_task() const;
/**
* @brief <20><>ȡ<EFBFBD><C8A1>ǰ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>͵ĵ<CDB5>ǰ֡<C7B0><D6A1><EFBFBD><EFBFBD>֡<EFBFBD><D6A1>
* @param current_frame_index <20><>ǰ֡
* @param total_frames <20><>֡<EFBFBD><D6A1>
* @return <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD>
*/
bool get_send_file_progress(uint32_t& current_frame_index, uint32_t& total_frames) const;
// <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>--------------------------------------------------
// ͳ<><CDB3><EFBFBD><EFBFBD><EFBFBD>ݻ<EFBFBD><DDBB><EFBFBD>
struct PointFloatCache {
@@ -201,6 +296,7 @@ public:
std::vector<FileDownloadPacket> file_download_cache_; // <20>ļ<EFBFBD><C4BC><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD>
std::string current_filename_; // <20><>ǰ<EFBFBD><C7B0><EFBFBD>ص<EFBFBD><D8B5>ļ<EFBFBD><C4BC><EFBFBD>
std::string preupgrade_filepath_; // Ԥ<><D4A4><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
std::mutex file_cache_mutex_; // <20><><EFBFBD><EFBFBD><E6BBA5><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>Ƭ<EFBFBD><C6AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
@@ -247,6 +343,18 @@ public:
std::lock_guard<std::mutex> lock(file_cache_mutex_);
return current_filename_;
}
//<2F><><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
void set_preupgrade_filepath(const std::string& filepath) {
std::lock_guard<std::mutex> lock(file_cache_mutex_);
preupgrade_filepath_ = filepath;
}
// <20><>ȡԤ<C8A1><D4A4><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
std::string get_preupgrade_filepath() {
std::lock_guard<std::mutex> lock(file_cache_mutex_);
return preupgrade_filepath_;
}
private:
int index_;
@@ -403,6 +511,8 @@ public:
bool update_current_filename(const std::string& identifier, const std::string& filename);
std::string get_current_filename(const std::string& identifier);
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ԤУ<D4A4><D0A3><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
std::string get_preupgrade_filepath(const std::string& identifier);
//ˢ<>¿ͻ<C2BF><CDBB><EFBFBD>װ<EFBFBD><D7B0><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD>ͨѶ<CDA8><D1B6><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
bool set_cloudmessage_time(const std::string& identifier);
@@ -419,6 +529,27 @@ public:
//<2F>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ص<EFBFBD><D8B5><EFBFBD> <20><><EFBFBD><EFBFBD>mac/id + <20>ļ<EFBFBD>λ<EFBFBD><CEBB>
bool add_file_download_action_to_device(const std::string& identifier, const std::string& file_path);
/**
* @brief <20><><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>װ<EFBFBD><D7B0><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
* @param file_path <20>ļ<EFBFBD>ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
*/
bool add_file_delete_action_to_device(const std::string& identifier, const std::string& file_path);
/**
* @brief <20><><EFBFBD>ɴ<EFBFBD><C9B4><EFBFBD>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD>
* @param file_path <20>ļ<EFBFBD>ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
*/
bool add_menu_set_action_to_device(const std::string& identifier, const std::string& file_path);
/**
* @brief <20><><EFBFBD><EFBFBD>ɾ<EFBFBD><C9BE>Ŀ¼<C4BF><C2BC><EFBFBD><EFBFBD>
* @param file_path <20>ļ<EFBFBD>ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
*/
bool add_menu_del_action_to_device(const std::string& identifier, const std::string& file_path);
//<2F><>ȡָ<C8A1><D6B8>װ<EFBFBD><D7B0>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>µĶ<C2B5>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>mac/id + <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool get_fixedvalue_action_to_device(const std::string& identifier, ushort point_id);
@@ -446,6 +577,61 @@ public:
//װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>
bool set_righttime_action_to_device(const std::string& identifier);
/**
* @brief <20><><EFBFBD><EFBFBD>Ԥ<EFBFBD><D4A4><EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><E9B1A8>
* @param path ԤУ<D4A4><D0A3><EFBFBD>ļ<EFBFBD>·<EFBFBD><C2B7>
* @return <20><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
*/
bool set_preupgrade_action_to_device(const std::string& identifier, const std::string& path);
/**
* @brief װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD>ͳ<EFBFBD>ʼ֡
* @param file <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>
* @param sin_length <20><><EFBFBD>͵<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
* @return <20><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
*/
bool send_upgrade_action_to_device(const std::string& identifier, const std::vector<unsigned char>& file, int sin_length);
/**
* @brief װ<><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡<D2BB><D6A1><EFBFBD><EFBFBD>
* @param identifier װ<>ñ<EFBFBD>ʶ<EFBFBD><CAB6>device_id <20><> mac<61><63>
* @param current_frame_index <20><>ȡ<EFBFBD><C8A1>ǰ֡(0-based<65><64><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>һ<EFBFBD><D2BB>Ҫ<EFBFBD><D2AA><EFBFBD>͵<EFBFBD>֡<EFBFBD><D6A1>)
* @param total_frames <20><>ȡ<EFBFBD><C8A1>֡<EFBFBD><D6A1>
* @param all_sent <20>Ƿ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param packet <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡<D2BB><D6A1><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ѷ<EFBFBD><D1B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
* @return <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
*/
bool try_get_next_upgrade_packet_to_device(const std::string& identifier,
uint32_t& current_frame_index,
uint32_t& total_frames,
bool& all_sent,
std::vector<unsigned char>& packet);
/**
* @brief <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD> <20><><EFBFBD>ͳ<EFBFBD>ʼ֡
* @param file <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD>
* @param sin_length <20><><EFBFBD>͵<EFBFBD>֡<EFBFBD><D6A1><EFBFBD><EFBFBD>
* @param dest_file_path װ<>ö<EFBFBD>Ŀ<EFBFBD><C4BF>ȫ·<C8AB><C2B7>
* @return <20><><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD>
*/
bool send_file_action_to_device(const std::string& identifier,
const std::vector<unsigned char>& file,
int sin_length,
const std::string& dest_file_path);
/**
* @brief <20>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>Ͷ<EFBFBD><CDB6><EFBFBD> <20><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡<D2BB><D6A1><EFBFBD><EFBFBD>
* @param identifier װ<>ñ<EFBFBD>ʶ<EFBFBD><CAB6>device_id <20><> mac<61><63>
* @param current_frame_index <20><>ȡ<EFBFBD><C8A1>ǰ֡(0-based<65><64><EFBFBD><EFBFBD>ʾ<EFBFBD><CABE>һ<EFBFBD><D2BB>Ҫ<EFBFBD><D2AA><EFBFBD>͵<EFBFBD>֡<EFBFBD><D6A1>)
* @param total_frames <20><>ȡ<EFBFBD><C8A1>֡<EFBFBD><D6A1>
* @param all_sent <20>Ƿ<EFBFBD>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
* @param packet <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ֡<D2BB><D6A1><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>ѷ<EFBFBD><D1B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>
* @return <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>
*/
bool try_get_next_send_file_packet_to_device(const std::string& identifier,
uint32_t& current_frame_index,
uint32_t& total_frames,
bool& all_sent,
std::vector<unsigned char>& packet);
//<2F><EFBFBD><E8B1B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>
bool get_dev_status(const std::string& identifier);
/**
@@ -457,6 +643,13 @@ public:
* @return <20><><EFBFBD>óɹ<C3B3><C9B9><EFBFBD>ʧ<EFBFBD>ܵĽ<DCB5><C4BD><EFBFBD>
*/
bool read_eventlog_action_to_device(const std::string& identifier, const std::tm& Time1, const std::tm& Time2,uint8_t eventType = 2, uint8_t monitorPoint = 1);
/**
* @brief <20><><EFBFBD><EFBFBD>װ<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EEB1A8>
* @param type <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1-װ<>ø<EFBFBD>λ<EFBFBD><CEBB>2-<2D><><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD>3-<2D><><EFBFBD><EFBFBD>200ms<6D><73><EFBFBD>ݼ<EFBFBD>¼<EFBFBD><C2BC>4-<2D><><EFBFBD><EFBFBD>3<EFBFBD><33><EFBFBD><EFBFBD><EFBFBD>ݼ<EFBFBD>¼
* @param ctrlflag <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3> <20>״δ<D7B4><CEB4><EFBFBD>0x00 <20><><EFBFBD><EFBFBD>У<EFBFBD><D0A3>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD> 0x01ִ<31><D6B4> 0x02ȡ<32><C8A1>
* @return <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5>ֽ<EFBFBD><D6BD><EFBFBD><EFBFBD><EFBFBD>
*/
bool set_ctrl_action_to_device(const std::string& identifier, uint8_t type, uint8_t ctrlflag);
private:
ClientManager() : loop_(nullptr) {}
std::unordered_map<std::string, std::unique_ptr<ClientContext>> clients_;

File diff suppressed because it is too large Load Diff

View File

@@ -133,10 +133,85 @@ void SendJsonAPI_web(const std::string& strUrl, //接口路径
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////下载文件流式接口
size_t req_reply_file_web(void* ptr, size_t size, size_t nmemb, void* userdata)
{
std::ofstream* out = static_cast<std::ofstream*>(userdata);
size_t total = size * nmemb;
if (out && out->is_open()) {
out->write(static_cast<const char*>(ptr), total);
}
return total;
}
bool DownloadFileAPI_web(const std::string& strUrl, // 接口路径
const std::string& code, // URL参数
const std::string& json, // POST body可为空
const std::string& save_path)// 本地保存路径
{
CURL* curl = curl_easy_init();
CURLcode res;
if (!curl) {
std::cerr << ">>> web curl init failed" << std::endl;
return false;
}
std::ofstream outFile(save_path.c_str(), std::ios::out | std::ios::binary);
if (!outFile.is_open()) {
std::cerr << ">>> open file failed: " << save_path << std::endl;
curl_easy_cleanup(curl);
return false;
}
std::string fullUrl = strUrl + "?" + code;
std::cout << ">>>file " << fullUrl << std::endl;
curl_easy_setopt(curl, CURLOPT_URL, fullUrl.c_str());
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, req_reply_file_web);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &outFile);
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 60);
if (!json.empty()) {
curl_easy_setopt(curl, CURLOPT_POST, 1L);
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, json.c_str());
}
struct curl_slist* headers = nullptr;
headers = curl_slist_append(headers, "Content-Type: application/json");
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, headers);
res = curl_easy_perform(curl);
long http_code = 0;
curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
outFile.close();
curl_slist_free_all(headers);
curl_easy_cleanup(curl);
if (res != CURLE_OK) {
std::cerr << "web failed, res code: " << curl_easy_strerror(res) << std::endl;
remove(save_path.c_str()); // 下载失败删除残文件
return false;
}
if (http_code != 200) {
std::cerr << "web http failed, http_code: " << http_code << std::endl;
remove(save_path.c_str());
return false;
}
std::cout << ">>> file download success: " << save_path << std::endl;
return true;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////上传文件接口
//处理文件上传响应
void handleUploadResponse(const std::string& response, std::string& wavepath) {
void handleUploadResponse(const std::string& response, std::string& wavepath, int type) {
using nlohmann::json; //把 nlohmann::json 这个名字带到当前作用域
@@ -183,13 +258,22 @@ void handleUploadResponse(const std::string& response, std::string& wavepath) {
// 找到最后一个 '.'
size_t pos = name.find_last_of('.');
std::string nameWithoutExt;
if (pos != std::string::npos) {
// 截取去掉后缀的部分
nameWithoutExt = name.substr(0, pos);
} else {
// 如果没有后缀,直接使用原文件名
nameWithoutExt = name;
if(1 == type) {
if (pos != std::string::npos) {
// 截取去掉后缀的部分
nameWithoutExt = name.substr(0, pos); //去掉路径后缀的名
} else {
// 如果没有后缀,直接使用原文件名
nameWithoutExt = name;
}
}
else if(2 == type) {
nameWithoutExt = name;//带路径全名
}
else{
nameWithoutExt = fileName;//没有路径的全名
}
// 拷贝到 wavepath
wavepath = nameWithoutExt;
@@ -199,7 +283,7 @@ void handleUploadResponse(const std::string& response, std::string& wavepath) {
}
//上传文件
void SendFileWeb(const std::string& strUrl, const std::string& localpath, const std::string& cloudpath, std::string& wavepath) {
void SendFileWeb(const std::string& strUrl, const std::string& localpath, const std::string& cloudpath, std::string& wavepath, int type) {
// 基本存在性检查
if (access(localpath.c_str(), F_OK) != 0) {
@@ -274,7 +358,7 @@ void SendFileWeb(const std::string& strUrl, const std::string& localpath, const
DIY_ERRORLOG_CODE("process",0,LOG_CODE_CONFIG, "通过文件接口上传文件 %s 失败",localpath.c_str());
} else {
std::cout << "http web success, response: " << resPost0 << std::endl;
handleUploadResponse(resPost0, wavepath); // 处理响应
handleUploadResponse(resPost0, wavepath, type); // 处理响应
}
// 清理
@@ -289,7 +373,7 @@ void SendFileWeb(const std::string& strUrl, const std::string& localpath, const
//上传暂态文件
void SOEFileWeb(std::string& localpath,std::string& cloudpath, std::string& wavepath)
{
SendFileWeb(WEB_FILEUPLOAD,localpath,cloudpath,wavepath);
SendFileWeb(WEB_FILEUPLOAD,localpath,cloudpath,wavepath,1);
}
//上传文件测试函数
@@ -302,6 +386,115 @@ void Fileupload_test()
std::cout << "wavepath:" << wavepath << std::endl;
}
/////////////////////////////////////////////////////////////////////////////////////////////////////下载文件接口通用
// 下载文件:从远端路径下载到本地,并返回本地文件路径
// 入参dev设备、remote_path远端完整路径
// 返回:本地保存路径(失败返回空字符串)
std::string getfilefromweb(const std::string& devid, const std::string& remote_path,int type)
{
try {
terminal_dev* dev = nullptr;
{
std::lock_guard<std::mutex> lock(ledgermtx);
for (auto& d : terminal_devlist) {
if (d.terminal_id == devid) {
dev = &d;
break;
}
}
}
if (!dev) {
std::cerr << "[getfile][ERROR] dev not found, id=" << devid << std::endl;
return "";
}
//【1】清洗远端路径防止 \0 问题)
std::string clean_remote = sanitize(remote_path);
//【2】提取文件名去掉路径只保留最后一段
auto get_filename = [](const std::string& path) -> std::string {
size_t pos1 = path.find_last_of('/');
size_t pos2 = path.find_last_of('\\');
size_t pos = std::string::npos;
if (pos1 == std::string::npos) pos = pos2;
else if (pos2 == std::string::npos) pos = pos1;
else pos = std::max(pos1, pos2);
return (pos == std::string::npos) ? path : path.substr(pos + 1);
};
std::string filename = get_filename(clean_remote);
//【3】构造本地保存路径
std::string mac = sanitize(normalize_mac(dev->addr_str));
std::string save_dir;
if(type == 1) {
// 升级文件放在专门的upgrade目录下
save_dir = std::string(FRONT_PATH) + "/bin/upgrade/" + mac + "/";
}
else {
// 普通文件放在upload目录下
save_dir = std::string(FRONT_PATH) + "/bin/upload/" + mac + "/";
}
if (!create_directory_recursive(save_dir)) {
std::cerr << "[getfile][ERROR] create dir failed: " << save_dir << std::endl;
return "";
}
std::string save_path = save_dir + filename;
std::cout << "[getfile] remote: " << clean_remote
<< " -> local: " << save_path << std::endl;
//【4】构造接口入参
//std::string fileContent;
std::string fullPath = "filePath=" + clean_remote;
std::cout << "[getfile] request param: " << fullPath << std::endl;
//【5】调用下载接口
if (!DownloadFileAPI_web(WEB_FILEDOWNLOAD, fullPath, "", save_path)) {
std::cerr << "[getfile][ERROR] download failed: " << clean_remote << std::endl;
return "";
}
/*SendJsonAPI_web(WEB_FILEDOWNLOAD, fullPath.c_str(), "", fileContent);
//【6】判断返回
if (fileContent.empty()) {
std::cerr << "[getfile][ERROR] download failed, empty content" << std::endl;
return "";
}
//【7】写文件
std::ofstream outFile(save_path, std::ios::out | std::ios::binary);
if (!outFile.is_open()) {
std::cerr << "[getfile][ERROR] cannot open file: " << save_path << std::endl;
return "";
}
outFile.write(fileContent.c_str(), fileContent.size());
outFile.close();*/
std::cout << "[getfile] File saved successfully: " << save_path << std::endl;
//【8】返回本地路径
return save_path;
}
catch (const std::exception& e) {
std::cerr << "[getfile][EXCEPTION] " << e.what() << std::endl;
}
catch (...) {
std::cerr << "[getfile][EXCEPTION] unknown error" << std::endl;
}
return "";
}
//////////////////////////////////////////////////////////////////////////////////////////////////////映射文件下载接口
void download_xml_for_icd(const std::string& MODEL_ID,
const std::string& TMNL_TYPE,
@@ -641,7 +834,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
dev.processNo = safe_str(item, "node");
dev.maxProcessNum = safe_str(item, "maxProcessNum");
//dev.mac = safe_str(item, "mac");//添加mac
dev.mac = safe_str(item, "ip");//添加mac
if (item.contains("monitorData") && item["monitorData"].is_array()) {
for (auto& mon : item["monitorData"]) {

View File

@@ -687,7 +687,7 @@ bool update_qvvr_file_download(const std::string& filename_with_mac, const std::
//上送文件列表接口
bool send_file_list(terminal_dev* dev, const std::vector<tag_dir_info> &FileList);
std::string getfilefromweb(const std::string& devid, const std::string& remote_path,int type);
//提取mac
std::string normalize_mac(const std::string& mac);
@@ -718,7 +718,7 @@ bool save_internal_value(const std::string &dev_id, const std::vector<ushort> &f
bool save_set_value(const std::string &dev_id, unsigned char mp_index, const std::vector<float> &fabsf);
//发送文件
void SendFileWeb(const std::string& strUrl, const std::string& localpath, const std::string& cloudpath, std::string& wavepath);
void SendFileWeb(const std::string& strUrl, const std::string& localpath, const std::string& cloudpath, std::string& wavepath,int Type);
//状态翻转
void connect_status_update(const std::string& id, int status);
@@ -753,6 +753,9 @@ void filemenu_cache_put(const std::string& dev_id,
//提取目录信息
bool filemenu_cache_take(const std::string& dev_id, std::vector<tag_dir_info>& out);
//清空装置台账
size_t erase_one_terminals_by_id(const std::string& terminal_id);
@@ -980,7 +983,6 @@ static bool parse_datetime_tm(const std::string& s, std::tm& out) {
std::memset(&out, 0, sizeof(out));
return strptime(s.c_str(), "%Y-%m-%d %H:%M:%S", &out) != nullptr;
}
#endif
/////////////////////////////////////////////////////////////////////////////补招文件记录
// 记录 (guid, monitorId) -> 文件完整路径
@@ -1016,3 +1018,55 @@ bool SendFileWebAuto(const std::string& id,
std::string& out_filename);
void cleanup_old_unpaired_qvvr_events();
// 运行信息
struct RunningInformation {
std::string Time;
std::string CpuLoad;
std::string FreeMemory;
std::string TotalMemory;
std::string FreeStorage;
std::string TotalStorage;
std::string HardTimeSync;
std::string SntpTimeSync;
std::string CloudTimeSync;
std::string SignalStrength;
};
// 版本信息
struct DeviceVersionInfo {
std::string BaseModel; // 1
std::string CloudProtocolVer; // 2
std::string AppVersion; // 3
std::string AppDate; // 4
std::string AppChecksum; // 5
std::string VoltageWiring; // 6
std::string CurrentBSynthetic; // 7
int DataStatInterval = 0; // 8
float RatedVoltage = 0.0f; // 9
float PTRatio = 0.0f; // 10
float CTRatio = 0.0f; // 11
std::string SntpIP; // 12
int SntpPort = 0; // 13
int SntpInterval = 0; // 14
int WebPort = 0; // 15
int FtpPort = 0; // 16
int PqdifInterval = 0; // 17
int WaveFileTypeCount = 0; // 18
std::string SpecialVersion; // 19
std::string DeviceModel; // 20
int HarmonicEnergyFlag = 0; // 21
std::string PhysicalName; // 22
std::string WaveLDName; // 23
int HighFreqHarmonicFlag = 0; // 24
unsigned int CommProtocols = 0; // 51
unsigned int TimeSyncMethods = 0;// 52
unsigned int DeviceFunctions = 0;// 53
};
void runninginfo_cache_put(const std::string& dev_id, const RunningInformation& info);
bool runninginfo_cache_take(const std::string& dev_id, RunningInformation& out);
void versioninfo_cache_put(const std::string& dev_id, const DeviceVersionInfo& info);
bool versioninfo_cache_take(const std::string& dev_id, DeviceVersionInfo& out);
#endif

View File

@@ -50,6 +50,14 @@ extern std::string subdir;
//日志主题
extern std::string G_LOG_TOPIC;
// 日志限流配置
extern int G_LOG_RATE_RESET_SEC;
extern int G_LOG_RATE_LIMIT_SEC;
extern int G_LOG_RATE_KEEP_ALL_MS;
extern int G_LOG_RATE_KEEP_BURST_MS;
extern int G_LOG_RATE_KEEP_BURST_COUNT;
extern int G_LOG_RATE_KEEP_HIGHFREQ_COUNT;
////////////////////////////////////////////////////////////////////////////////////////////////////
const int LOGTYPE_DEFAULT = LOG_CODE_OTHER;
@@ -92,16 +100,35 @@ std::string build_debug_key(const std::string& id, const std::string& level, int
// 递归创建目录
bool create_directory_recursive(const std::string& path) {
size_t pos = 0;
bool create_directory_recursive(const std::string& path)
{
if (path.empty()) return false;
std::string current;
while (pos != std::string::npos) {
pos = path.find('/', pos + 1);
current = path.substr(0, pos);
if (!current.empty() && access(current.c_str(), F_OK) != 0) {
if (mkdir(current.c_str(), 0755) != 0) {
perror(("mkdir failed: " + current).c_str());
return false;
current.reserve(path.size());
for (size_t i = 0; i < path.size(); ++i) {
current += path[i];
// 遇到 '/' 或最后一个字符时创建
if (path[i] == '/' || i == path.size() - 1) {
if (current.empty()) continue;
// 去掉末尾 '/'
std::string dir = current;
if (dir.back() == '/' && dir.size() > 1) {
dir.pop_back();
}
struct stat st;
if (stat(dir.c_str(), &st) != 0) {
if (mkdir(dir.c_str(), 0755) != 0) {
// 如果已经存在(并发场景),忽略
if (errno != EEXIST) {
perror(("mkdir failed: " + dir).c_str());
return false;
}
}
}
}
}
@@ -204,10 +231,26 @@ void refresh_log_level_cache_locked()
class SendAppender : public Appender {
private:
struct RateState {
/*struct RateState {
uint64_t hit_count = 0; // 同一条日志累计命中次数
std::chrono::steady_clock::time_point last_emit =
std::chrono::steady_clock::time_point::min();
};*/
struct RateState {
uint64_t pass_count; // 当前周期内已放行条数
uint64_t suppressed_count; // 当前被抑制条数
std::chrono::steady_clock::time_point last_emit;
std::chrono::steady_clock::time_point last_seen;
std::chrono::steady_clock::time_point last_reset;
bool has_emit;
RateState()
: pass_count(0),
suppressed_count(0),
last_emit(),
last_seen(),
last_reset(),
has_emit(false) {}
};
static std::unordered_map<std::string, RateState> s_rate_map; //频率map
@@ -221,7 +264,7 @@ private:
}
// 前 3 次1 秒一次;第 3 次起300 秒一次,一小时恢复
static bool should_emit(const std::string& key) {
/*static bool should_emit(const std::string& key) {
using namespace std::chrono;
const auto now = steady_clock::now();
@@ -252,6 +295,96 @@ private:
return true;
}
return false;
}*/
static bool should_emit(const std::string& key, uint64_t& suppressed_before_emit) {
using namespace std::chrono;
const auto now = steady_clock::now();
suppressed_before_emit = 0;
std::lock_guard<std::mutex> lk(s_rate_mutex);
RateState& st = s_rate_map[key];
const int RESET_SEC = G_LOG_RATE_RESET_SEC ; // 1小时重置
const int LIMIT_SEC = G_LOG_RATE_LIMIT_SEC ; // 进入限流后多久发1条 主要控制中频和高频那些,低频的都直接放行了
// 初始化 / 强制每小时重置
if (st.last_reset.time_since_epoch().count() == 0) {
st.last_reset = now;
} else {
auto since_reset = duration_cast<seconds>(now - st.last_reset).count();
if (since_reset >= RESET_SEC) { //重置周期
st = RateState();
st.last_reset = now;
}
}
// 计算当前频率档位按“本次与上次看到该key的间隔”判断
// >=60秒/条:全部保留
// [1秒, 60秒)保留前60条然后1分钟1条
// <1秒保留前10条然后1分钟1条
int allow_burst = 0;
if (st.last_seen.time_since_epoch().count() == 0) {
// 第一次看到,先按“全部保留”处理
allow_burst = -1;
} else {
auto gap_ms = duration_cast<milliseconds>(now - st.last_seen).count();
if (gap_ms >= G_LOG_RATE_KEEP_ALL_MS) { //什么时候不需要限流 //低频 //如果这里设置的很低,就不会限流
allow_burst = -1; // 全部保留
} else if (gap_ms >= G_LOG_RATE_KEEP_BURST_MS) {
allow_burst = G_LOG_RATE_KEEP_BURST_COUNT; // 前60条 //中频 //如果这里设置的比低频低,也不会生效
} else {
allow_burst = G_LOG_RATE_KEEP_HIGHFREQ_COUNT; // 前10条 //高频
}
}
st.last_seen = now;
// 档位1全部保留
if (allow_burst == -1) {
suppressed_before_emit = st.suppressed_count;
st.suppressed_count = 0;
st.pass_count++;
st.last_emit = now;
st.has_emit = true;
return true;
}
// 档位2/3先放前N条
if (st.pass_count < (uint64_t)allow_burst) {
suppressed_before_emit = st.suppressed_count;
st.suppressed_count = 0;
st.pass_count++;
st.last_emit = now;
st.has_emit = true;
return true;
}
// 超过前N条后进入 1分钟1条
if (!st.has_emit) {
suppressed_before_emit = st.suppressed_count;
st.suppressed_count = 0;
st.pass_count++;
st.last_emit = now;
st.has_emit = true;
return true;
}
auto elapsed = duration_cast<seconds>(now - st.last_emit).count();
if (elapsed >= LIMIT_SEC) {
suppressed_before_emit = st.suppressed_count;
st.suppressed_count = 0;
st.pass_count++;
st.last_emit = now;
st.has_emit = true;
return true;
}
// 本条被抑制
st.suppressed_count++;
return false;
}
@@ -377,8 +510,17 @@ protected:
// ★新增:限频判断(同一条日志前 5 次 1 秒一次;之后 300 秒一次)
const std::string key = make_key(logger_name, level, code, msg);
if (!should_emit(key)) {
return;
uint64_t suppressed_before_emit = 0;
if (!should_emit(key, suppressed_before_emit)) return;
// 如果本次输出前压掉过日志,则在 log 文本后追加统计
std::string final_msg = msg;
if (suppressed_before_emit > 0) {
std::ostringstream suppressed_oss;
suppressed_oss << msg << " 【已过滤重复同类日志 "
<< suppressed_before_emit
<< " 条】";
final_msg = suppressed_oss.str();
}
std::ostringstream oss;
@@ -390,7 +532,7 @@ protected:
<< "\",\"grade\":\"" << get_level_str(level)
// ★建议code 用数字(不是字符串)
<< "\",\"code\":" << code
<< ",\"log\":\"" << escape_json(msg) << "\"}";
<< ",\"log\":\"" << escape_json(final_msg) << "\"}";
queue_data_t connect_info;
connect_info.strTopic = G_LOG_TOPIC;

View File

@@ -97,6 +97,8 @@ void update_log_entries_countdown();
void refresh_log_level_cache_locked();
bool create_directory_recursive(const std::string& path);
extern "C" {
#endif
void remove_loggers_by_terminal_id(const std::string& terminal_id_cstr);

View File

@@ -565,6 +565,8 @@ void Front::mqconsumerThread()
subscriptions.emplace_back(G_MQCONSUMER_TOPIC_SET, FRONT_INST, myMessageCallbackset);
subscriptions.emplace_back(G_MQCONSUMER_TOPIC_LOG, FRONT_INST, myMessageCallbacklog);
subscriptions.emplace_back(G_MQCONSUMER_TOPIC_CLOUD, FRONT_INST, cloudMessageCallback);
m_mqConsumer = make_unique<rocketmq::DefaultMQPushConsumer>(consumerGroup);

View File

@@ -77,6 +77,9 @@ extern std::atomic<int> INITFLAG;
//测试用的终端数组
extern std::vector<std::string> TESTARRAY;
extern std::map<std::string, std::string> g_upgrade_file_map;
extern std::mutex g_upgrade_file_mutex;
////////////////////////////////////////////////////////////////////////////////////////////////////////外部文件函数声明
extern void execute_bash(std::string fun,int process_num,std::string type);
@@ -767,9 +770,10 @@ bool parseJsonMessageUD(const std::string& json_str, const std::string& output_d
}
json_data.processNo = std::to_string(procNo);
//int procNum = item.value("maxProcessNum", -1);
//json_data.maxProcessNum = std::to_string(procNum);
int procNum = item.value("maxProcessNum", -1);
json_data.maxProcessNum = std::to_string(procNum);
json_data.addr_str = item.value("ip", "");
json_data.mac = item.value("ip", "");
//json_data.port = item.value("port", "");
//json_data.timestamp = item.value("updateTime", "");
@@ -2071,11 +2075,37 @@ bool parseJsonMessageCLOUD(const std::string &body,
std::string &devid,
std::string &guid,
nlohmann::json &detailObj, // 这里返回整个 Detail
std::string &front_ip, // 新增:返回 FrontIP
std::string &front_id, // 新增:返回 FrontId
int &node) // 新增:返回 Node
{
try {
auto j = nlohmann::json::parse(body);
// ====== 先解析外层 JSON ======
auto outer = nlohmann::json::parse(body);
// ====== 提取 messageBody 字符串 ======
if (!outer.contains("messageBody") || !outer["messageBody"].is_string()) {
std::cerr << "[parseJsonMessageCLOUD] 'messageBody' is missing or is not a string\n";
guid.clear();
devid.clear();
front_id.clear();
node = 0;
detailObj = nlohmann::json::object();
return false;
}
std::string messageBodyStr = outer["messageBody"].get<std::string>();
if (messageBodyStr.empty()) {
std::cerr << "[parseJsonMessageCLOUD] 'messageBody' is empty\n";
guid.clear();
devid.clear();
front_id.clear();
node = 0;
detailObj = nlohmann::json::object();
return false;
}
// ====== 再解析 messageBody 内层 JSON ======
auto j = nlohmann::json::parse(messageBodyStr);
// guid
if (j.contains("guid") && j["guid"].is_string()) {
@@ -2084,11 +2114,11 @@ bool parseJsonMessageCLOUD(const std::string &body,
guid.clear();
}
// FrontIP
if (j.contains("FrontIP") && j["FrontIP"].is_string()) {
front_ip = j["FrontIP"].get<std::string>();
// FrontId
if (j.contains("FrontId") && j["FrontId"].is_string()) {
front_id = j["FrontId"].get<std::string>();
} else {
front_ip.clear();
front_id.clear();
}
// Node
@@ -2128,7 +2158,7 @@ bool parseJsonMessageCLOUD(const std::string &body,
std::cerr << "[parseJsonMessageCLOUD] JSON parse error: " << e.what() << "\n";
guid.clear();
devid.clear();
front_ip.clear();
front_id.clear();
node = 0;
detailObj = nlohmann::json::object();
return false;
@@ -2171,7 +2201,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
if (detailObj.contains("Type")) {
if (detailObj["Type"].is_string()) {
try {
parsed.type = std::stoi(detailObj["Type"].get<std::string>(), nullptr, 0); // 支持 "0x2106" 格式
parsed.type = std::stoi(detailObj["Type"].get<std::string>(), nullptr, 0); // 支持 "1103" 格式
} catch (...) {
return false;
}
@@ -2195,13 +2225,27 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
try {
switch (parsed.type) {
case 0x2131: { // 读取目录
case 1101: { // 读取目录
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
if(!recordguid(devid,guid,static_cast<int>(DeviceState::READING_FILEMENU),1)){
int ret = recordguid(devid,guid,static_cast<int>(DeviceState::READING_FILEMENU),1);
if(-1 == ret){ //0记录成功往下执行1装置正忙-1未找到装置
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND), //响应
"未找到该装置,读取目录指令执行失败");
DIY_ERRORLOG_CODE(devid,1,LOG_CODE_CLOUD, "未找到该装置,读取目录指令执行失败"); //日志记录
return true;
}
else if(ret > 0){
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,读取目录指令执行失败");
DIY_WARNLOG_CODE(devid,1,LOG_CODE_CLOUD, "该装置正忙,读取目录指令执行失败");
return true;
}
else{
std::cout << "记录装置状态成功,准备读取目录" << std::endl; //调试输出
DIY_INFOLOG_CODE(devid,1,LOG_CODE_CLOUD, "记录装置状态成功,准备读取目录");
}
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
parsed.name = msgObj["Name"].get<std::string>();
parsed.ok = true;
@@ -2212,13 +2256,29 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
return true;
}
case 0x2132: { // 下载文件
if(!recordguid(devid,guid,static_cast<int>(DeviceState::READING_FILEDATA),1)){
return true;
case 1102: { // 下载文件
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::READING_FILEDATA), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,下载文件指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,下载文件指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,下载文件指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,下载文件指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备下载文件" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备下载文件");
}
}
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
parsed.name = msgObj["Name"].get<std::string>();
parsed.ok = true;
@@ -2229,7 +2289,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
return true;
}
case 0x2106: { // 定值/内部定值
case 1103: { // 定值/内部定值
if (!msgObj.contains("Cldid") || !msgObj["Cldid"].is_number_integer()) return false;
if (!msgObj.contains("DataType") || !msgObj["DataType"].is_number_integer()) return false;
if (!msgObj.contains("Operate") || !msgObj["Operate"].is_number_integer()) return false;
@@ -2250,7 +2310,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
parsed.dataArray_us.clear();
switch (parsed.datatype) {
case 0x0C: { // 定值float 阵列)
case 1: { // 定值float 阵列)
for (const auto& v : msgObj["DataArray"]) {
if (!v.is_number()) return false;
@@ -2259,7 +2319,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
}
// 打印 DataArray
std::cout << "[0x0C] DataArray=[";
std::cout << "[1] DataArray=[";
for (size_t i = 0; i < parsed.dataArray_f.size(); ++i) {
std::cout << parsed.dataArray_f[i] << (i + 1 < parsed.dataArray_f.size() ? ", " : "");
}
@@ -2271,8 +2331,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
switch (parsed.operate) {
case 1: { // 读
if(!recordguid(devid,guid,static_cast<int>(DeviceState::READING_FIXEDVALUE),2)){
return true;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::READING_FIXEDVALUE), 2);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,读取定值指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,读取定值指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,读取定值指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,读取定值指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备读取定值" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备读取定值");
}
}
ClientManager::instance().get_fixedvalue_action_to_device(
@@ -2282,8 +2358,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
}
case 2: { // 写
if(!recordguid(devid,guid,static_cast<int>(DeviceState::SET_FIXEDVALUE),1)){
return true;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::SET_FIXEDVALUE), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,写定值指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,写定值指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,写定值指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,写定值指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备写定值" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备写定值");
}
}
ClientManager::instance().set_fixedvalue_action_to_device(
@@ -2296,7 +2388,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
break;
}
case 0x0D: { // 内部定值uint16_t 阵列)
case 2: { // 内部定值uint16_t 阵列)
for (const auto& v : msgObj["DataArray"]) {
if (!v.is_number_integer() && !v.is_number_unsigned()) return false;
// 范围校验 [0, 65535]
@@ -2306,7 +2398,7 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
}
// 打印 DataArray
std::cout << "[0x0D] DataArray=[";
std::cout << "[2] DataArray=[";
for (size_t i = 0; i < parsed.dataArray_us.size(); ++i) {
std::cout << parsed.dataArray_us[i] << (i + 1 < parsed.dataArray_us.size() ? ", " : "");
}
@@ -2318,8 +2410,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
switch (parsed.operate) {
case 1: { // 读
if(!recordguid(devid,guid,static_cast<int>(DeviceState::READING_INTERFIXEDVALUE),3)){
return true;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::READING_INTERFIXEDVALUE), 3);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,读取内部定值指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,读取内部定值指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,读取内部定值指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,读取内部定值指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备读取内部定值" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备读取内部定值");
}
}
ClientManager::instance().get_interfixedvalue_action_to_device(devid); // 获取内部定值
@@ -2329,8 +2437,24 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
}
case 2: { // 写
if(!recordguid(devid,guid,static_cast<int>(DeviceState::SET_INTERFIXEDVALUE),1)){
return true;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::SET_INTERFIXEDVALUE), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,写内部定值指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,写内部定值指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,写内部定值指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,写内部定值指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备写内部定值" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备写内部定值");
}
}
ClientManager::instance().set_interfixedvalue_action_to_device(devid, parsed.dataArray_us);
@@ -2349,6 +2473,414 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
return true;
}
////////lnk20260312新增读取运行状态、版本、对时、重启
case 1111: { // 读取运行状态
parsed.ok = true;
std::cout << "[parsemsg] read running status, devid=" << devid
<< ", guid=" << guid << std::endl;
//
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::READING_RUNNINGINFORMATION_1), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,读取运行状态指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,读取运行状态指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,读取运行状态指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,读取运行状态指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备读取运行状态" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备读取运行状态");
}
}
//
ClientManager::instance().read_runninginformation_action_to_device(devid);//主动触发,读取
return true;
}
case 1112: { // 读取版本信息
parsed.ok = true;
std::cout << "[parsemsg] read version info, devid=" << devid
<< ", guid=" << guid << std::endl;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::READING_DEVVERSION), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,读取版本信息指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,读取版本信息指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,读取版本信息指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,读取版本信息指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备读取版本信息" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备读取版本信息");
}
}
ClientManager::instance().read_devversion_action_to_device(devid);
return true;
}
case 1113: { // 对时
parsed.ok = true;
std::cout << "[parsemsg] time sync, devid=" << devid
<< ", guid=" << guid << std::endl;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::SET_RIGHTTIME_2), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,对时指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,对时指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,对时指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,对时指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备对时" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备对时");
}
}
//
ClientManager::instance().set_righttime_action_to_device(devid);
return true;
}
case 1114: { // 重启
parsed.ok = true;
std::cout << "[parsemsg] reboot device, devid=" << devid
<< ", guid=" << guid << std::endl;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::SET_CTRL), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,重启指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,重启指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,重启指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,重启指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备重启装置" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备重启装置");
}
}
ClientManager::instance().set_ctrl_action_to_device(devid,0x01,0x00);//尝试装置重启指令!
return true;
}
case 1120: { // 辅助升级
parsed.ok = true;
std::cout << "[parsemsg] upgrade device, devid=" << devid
<< ", guid=" << guid << std::endl;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::SET_PREUPGRADE), 2);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,辅助升级指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,辅助升级指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,辅助升级指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,辅助升级指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备执行升级预校验" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行升级预校验");
}
}
//辅助升级就是文件替换
//ClientManager::instance().set_preupgrade_action_to_device(devid, "");//尝试装置升级指令!第一步校验
return true;
}
case 1115: {
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
parsed.ok = true;
std::cout << "[parsemsg] update, devid=" << devid
<< ", guid=" << guid << std::endl;
//【1】recordguid
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::SET_PREUPGRADE), 2);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,装置升级指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,装置升级指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,装置升级指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,装置升级指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备执行装置升级" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行装置升级");
}
}
//【2】取参数加 sanitize
std::string remote_path = sanitize(msgObj["Name"].get<std::string>()); // 云端路径
std::cout << "[parsemsg][1115] remote=" << remote_path
<< std::endl;
//【3】先下载到本地
std::string local_path = getfilefromweb(devid, remote_path,1);//升级文件下载到本地的路径和普通文件不一样放在专门的upgrade目录下
if (local_path.empty()) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BAD_REQUEST),
"文件上送失败,下载源文件失败: " + remote_path);
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "装置升级失败,下载源文件失败");
return true;
}
{
std::lock_guard<std::mutex> lk(g_upgrade_file_mutex);
g_upgrade_file_map[devid] = local_path;
}
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "升级文件下载成功,准备执行装置升级");
ClientManager::instance().set_preupgrade_action_to_device(devid, "");//尝试装置升级指令!第一步校验
return true;
}
////////lnk20260312新增读取运行状态、版本、对时、重启
////////lnk20260402新增目录新建、删除文件删除文件上传
case 1116: { // 文件上送
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
if (!msgObj.contains("RemoteName") || !msgObj["RemoteName"].is_string()) return false;
parsed.ok = true;
std::cout << "[parsemsg] send file, devid=" << devid
<< ", guid=" << guid << std::endl;
//【1】recordguid
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::SEND_FILE), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,文件上送指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,文件上送指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,文件上送指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,文件上送指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备执行文件上送" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行文件上送");
}
}
//【2】取参数加 sanitize
std::string remote_path = sanitize(msgObj["Name"].get<std::string>()); // 云端路径
std::string dest_file_path = sanitize(msgObj["RemoteName"].get<std::string>()); // 装置路径
std::cout << "[parsemsg][1116] remote=" << remote_path
<< ", dest=" << dest_file_path << std::endl;
//【3】先下载到本地
std::string local_path = getfilefromweb(devid, remote_path,0);//普通文件下载到本地的路径
if (local_path.empty()) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BAD_REQUEST),
"文件上送失败,下载源文件失败: " + remote_path);
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "文件发送装置失败,下载源文件失败");
return true;
}
//【4】读取本地文件
std::ifstream in(local_path.c_str(), std::ios::in | std::ios::binary);
if (!in.is_open()) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BAD_REQUEST),
"文件上送失败,无法打开本地文件: " + local_path);
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "文件发送装置失败,无法打开本地文件");
return true;
}
std::vector<unsigned char> file_data;
in.seekg(0, std::ios::end);
std::streamoff file_size = in.tellg();
in.seekg(0, std::ios::beg);
if (file_size < 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BAD_REQUEST),
"文件上送失败,读取文件大小异常: " + local_path);
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "文件发送装置失败,读取文件大小异常");
return true;
}
file_data.resize(static_cast<size_t>(file_size));
if (file_size > 0) {
in.read(reinterpret_cast<char*>(&file_data[0]), file_size);
}
in.close();
//【5】下发到装置
if (!ClientManager::instance().send_file_action_to_device(
devid, file_data, 10240, dest_file_path)) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BAD_REQUEST),
"文件上送指令下发失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "文件上送指令下发失败");
return true;
}
return true;
}
case 1117: { // 文件删除
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
parsed.ok = true;
std::cout << "[parsemsg] delete file, devid=" << devid
<< ", guid=" << guid << std::endl;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::DEL_FILE), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,文件删除指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,文件删除指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,文件删除指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,文件删除指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备执行文件删除" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行文件删除");
}
}
std::string dev_file_name = msgObj["Name"].get<std::string>();
std::cout << "[parsemsg][1117] Name=" << dev_file_name << std::endl;
ClientManager::instance().add_file_delete_action_to_device(devid, dev_file_name);
return true;
}
case 1118: { // 目录创建
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
parsed.ok = true;
std::cout << "[parsemsg] create menu, devid=" << devid
<< ", guid=" << guid << std::endl;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::SEND_MENU), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,目录创建指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,目录创建指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,目录创建指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,目录创建指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备执行目录创建" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行目录创建");
}
}
std::string dir_name = msgObj["Name"].get<std::string>();
std::cout << "[parsemsg][1118] Name=" << dir_name << std::endl;
ClientManager::instance().add_menu_set_action_to_device(devid, dir_name);
return true;
}
case 1119: { // 目录删除
if (!msgObj.contains("Name") || !msgObj["Name"].is_string()) return false;
parsed.ok = true;
std::cout << "[parsemsg] delete menu, devid=" << devid
<< ", guid=" << guid << std::endl;
{
int ret = recordguid(devid, guid, static_cast<int>(DeviceState::DEL_MENU), 1);
if (-1 == ret) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::NOT_FOUND),
"未找到该装置,目录删除指令执行失败");
DIY_ERRORLOG_CODE(devid, 1, LOG_CODE_CLOUD, "未找到该装置,目录删除指令执行失败");
return true;
}
else if (ret > 0) {
send_reply_to_queue(guid, static_cast<int>(ResponseCode::BUSY),
"该装置正忙,目录删除指令执行失败");
DIY_WARNLOG_CODE(devid, 1, LOG_CODE_CLOUD, "该装置正忙,目录删除指令执行失败");
return true;
}
else {
std::cout << "记录装置状态成功,准备执行目录删除" << std::endl;
DIY_INFOLOG_CODE(devid, 1, LOG_CODE_CLOUD, "记录装置状态成功,准备执行目录删除");
}
}
std::string dir_name = msgObj["Name"].get<std::string>();
std::cout << "[parsemsg][1119] Name=" << dir_name << std::endl;
ClientManager::instance().add_menu_del_action_to_device(devid, dir_name);
return true;
}
////////lnk20260402新增目录新建、删除文件删除文件上传
default:
return false;
}
@@ -2361,7 +2893,33 @@ bool parsemsg(const std::string& devid, const std::string& guid, const nlohmann:
}
}
//心跳和其他响应
//////////////////////////////////////////////////////////////////////////////////////////////////////////云响应
static int get_cloud_type_by_state(int type)
{
switch (static_cast<DeviceState>(type)) {
case DeviceState::READING_FILEMENU: return 1101; // 读取文件目录
case DeviceState::READING_FILEDATA: return 1102; // 下载文件数据
case DeviceState::READING_FIXEDVALUE: return 1103; // 读取测点定值
case DeviceState::SET_FIXEDVALUE: return 1103; // 设置测点定值
case DeviceState::READING_INTERFIXEDVALUE: return 1103; // 读取内部定值
case DeviceState::SET_INTERFIXEDVALUE: return 1103; // 设置内部定值
case DeviceState::READING_RUNNINGINFORMATION_1: return 1111; // 主动读取运行状态
case DeviceState::READING_DEVVERSION: return 1112; // 读取版本信息
case DeviceState::SET_RIGHTTIME_2: return 1113; // 主动对时
case DeviceState::SET_CTRL: return 1114; // 控制/重启
case DeviceState::SET_PREUPGRADE: return 1115; // 升级预校验
case DeviceState::SEND_FILE: return 1116; // 文件上送
case DeviceState::DEL_FILE: return 1117; // 文件删除
case DeviceState::SEND_MENU: return 1118; // 目录创建
case DeviceState::DEL_MENU: return 1119; // 目录删除
default:
return type; // 其他未映射的,保持原值,避免影响现有逻辑
}
}
void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type, const std::string& guid, const std::string& mac) {
try {
/*std::string guid = find_guid_index_from_dev_id(dev_id);*/
@@ -2383,7 +2941,7 @@ void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type, co
// ---- 构造 Detail ----
nlohmann::json detail;
detail["Type"] = type;
detail["Type"] = get_cloud_type_by_state(type);
// Msg
nlohmann::json msg;
@@ -2397,10 +2955,10 @@ void send_reply_to_cloud(int reply_code, const std::string& dev_id, int type, co
// ---- 入队发送 ----
queue_data_t connect_info;
connect_info.strTopic = Topic_Reply_Topic;
connect_info.strTopic = Cloud_Reply_Topic;
connect_info.strText = obj.dump(); // 序列化为字符串
connect_info.tag = Topic_Reply_Tag;
connect_info.key = Topic_Reply_Key;
connect_info.tag = Cloud_Reply_Tag;
connect_info.key = Cloud_Reply_Key;
{
std::lock_guard<std::mutex> lock(queue_data_list_mutex);

View File

@@ -94,6 +94,10 @@ extern std::string G_MQCONSUMER_TOPIC_CLOUD;
extern std::string G_MQCONSUMER_TAG_CLOUD;
extern std::string G_MQCONSUMER_KEY_CLOUD;
extern std::string Cloud_Reply_Topic;
extern std::string Cloud_Reply_Tag;
extern std::string Cloud_Reply_Key;
extern std::string G_LOG_TOPIC;
extern std::string G_LOG_TAG;
extern std::string G_LOG_KEY;
@@ -336,6 +340,7 @@ rocketmq::ConsumeStatus myMessageCallbackrtdata(const rocketmq::MQMessageExt& ms
rocketmq::ConsumeStatus myMessageCallbackupdate(const rocketmq::MQMessageExt& msg);
rocketmq::ConsumeStatus myMessageCallbackset(const rocketmq::MQMessageExt& msg);
rocketmq::ConsumeStatus myMessageCallbacklog(const rocketmq::MQMessageExt& msg);
rocketmq::ConsumeStatus cloudMessageCallback(const rocketmq::MQMessageExt& msg);
void send_heartbeat_to_queue(const std::string& status);

View File

@@ -15,7 +15,6 @@
#include "cloudfront/code/rocketmq.h" //lnk20250708
#include "cloudfront/code/log4.h" //lnk20250924
#include "client2.h"
#include "cloudfront/code/log4.h"
using namespace std;
@@ -49,23 +48,104 @@ std::string extract_filename(const std::string& path) {
return path;
}
//文件crc校验函数
uint16_t crc_16_new(const uint8_t* buf, uint32_t len) {
uint16_t crc = 0xffff;
for (uint32_t i = 0; i < len; i++) {
crc = (uint16_t)(crc ^ buf[i]);
for (int j = 0; j < 8; j++) {
if (crc & 1) {
crc = (uint16_t)((crc >> 1) ^ 0xA001);
// 生成与 C# CreateNormalCrc32Table 完全对应的表
static std::array<uint32_t, 256> CreateNormalCrc32Table(uint32_t poly)
{
std::array<uint32_t, 256> table{};
for (int i = 0; i < 256; ++i)
{
uint32_t data = static_cast<uint32_t>(i) << 24;
for (int j = 0; j < 8; ++j)
{
bool flag = (data & 0x80000000u) == 0x80000000u;
if (flag)
{
data = (data << 1) ^ poly;
}
else {
crc = (uint16_t)(crc >> 1);
else
{
data <<= 1;
}
}
table[i] = data;
}
return table;
}
// 与 C# CalcNoemalCrc32 完全对应
static uint32_t CalcNormalCrc32(const std::vector<uint8_t>& bytes, uint32_t poly)
{
auto table = CreateNormalCrc32Table(poly);
uint32_t crc = 0xFFFFFFFFu;
for (size_t i = 0; i < bytes.size(); ++i)
{
crc = (crc << 8) ^ table[((crc >> 24) & 0xFFu) ^ bytes[i]];
}
return crc;
}
/* 生成预升级校验文件 算法 */
int new_tcp_pre_upgrade_message_create(uint8_t* buf, uint32_t len)
{
uint16_t i, j;
uint16_t value = 0xFFFF;
uint16_t factor = 0xA001;
if (len > 10 * 1024) {
len = 10 * 1024;
}
for (i = 0; i < len; i++)
{
value = value ^ static_cast<uint16_t>(i + 1);
for (j = 0; j < 8; j++)
{
if ((value & 1) == 1) {
value = static_cast<uint16_t>((value >> 1) ^ factor);
}
else {
value = static_cast<uint16_t>(value >> 1);
}
}
buf[i] = static_cast<uint8_t>(value & 0xFF);
}
return static_cast<int>(len);
}
//生成预升级校验文件
std::vector<uint8_t> GeneratePreUpgradeFileFromLengthBytes(uint32_t fileLen)
{
if (fileLen > 10 * 1024) {
throw std::runtime_error("Pre-upgrade file length exceeds maximum allowed size.");
}
std::vector<uint8_t> fileData(fileLen);
int actualLen = new_tcp_pre_upgrade_message_create(fileData.data(), fileLen);
fileData.resize(actualLen);
return fileData;
}
// 读取文件为二进制字节数组
std::vector<unsigned char> read_file_as_bytes(const std::string& file_path)
{
std::ifstream file(file_path, std::ios::binary);
if (!file.is_open()) {
std::cerr << "打开文件失败: " << file_path << std::endl;
return {};
}
return std::vector<unsigned char>(
std::istreambuf_iterator<char>(file),
std::istreambuf_iterator<char>()
);
}
//消息处理逻辑
void process_received_message(string mac, string id,const char* data, size_t length) {
// 实际的消息处理逻辑
@@ -94,9 +174,25 @@ void process_received_message(string mac, string id,const char* data, size_t len
ClientManager::instance().set_cloud_status(id, 1); //设置了云前置登录状态为已登录
ClientManager::instance().read_devversion_action_to_device(id);//主动触发,读取装置版本配置信息,仅在装置登录后执行一次,当前获取版本信息确认对时报文结构。
//std::vector<unsigned char> file_data = read_file_as_bytes("pqs_arm2.bin");
//ClientManager::instance().send_file_action_to_device(id, file_data,10240,"/etc/test1.bin");//默认单帧最大10240 文件上送流程
//std::vector<unsigned char> file_data = read_file_as_bytes("pqs_arm2.bin");
//ClientManager::instance().send_upgrade_action_to_device(id, file_data,10240);//默认单帧最大10240 程序升级流程
//ClientManager::instance().set_preupgrade_action_to_device(id, "");//装置升级预校验流程 校验文件自动生成 当前填空
//ClientManager::instance().set_ctrl_action_to_device(id,0x01,0x00);//尝试装置重启指令!
//ClientManager::instance().add_menu_set_action_to_device(id,"/etc/tt1");//创建目录
//ClientManager::instance().add_file_menu_action_to_device(id, "/etc");
//ClientManager::instance().add_menu_del_action_to_device(id, "/etc/tt1");//删除目录
//ClientManager::instance().add_file_menu_action_to_device(id, "/etc");
//ClientManager::instance().add_file_menu_action_to_device(id,"/etc");//测试文件目录读取
//ClientManager::instance().add_file_delete_action_to_device(id, "/etc/test1.bin");//文件删除功能
//ClientManager::instance().get_dev_status(id);//设备在线情况判断 ture在线 false离线
//ClientManager::instance().set_real_state_count("D002", 1,1);//登录后测试实时
//ClientManager::instance().add_file_menu_action_to_device(id,"/etc");//测试文件目录读取
//ClientManager::instance().add_file_download_action_to_device("D002", "/etc/NPQS570_VX_ZJ_2(V103).icd");//测试文件下载
//ClientManager::instance().get_fixedvalue_action_to_device(id,1);//测试获取装置测点定值数据
//ClientManager::instance().get_fixedvaluedes_action_to_device(id);//测试获取装置定值描述
@@ -148,6 +244,8 @@ void process_received_message(string mac, string id,const char* data, size_t len
//装置主动上送报文 暂态事件报文/暂态波形文件报文
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Event)) {
//处理主动上送的暂态事件报文
std::cout << "GET: MsgResponseType::Response_Event";
DIY_INFOLOG_CODE(id, 1, static_cast<int>(LogCode::LOG_CODE_TRANSIENT), "收到装置主动上送的暂态事件信息报文");
NewTaglogbuffer event = NewTaglogbuffer::createFromData(parser.RecvData.data(), parser.RecvData.size());
//获取测点id
@@ -269,6 +367,8 @@ void process_received_message(string mac, string id,const char* data, size_t len
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_ActiveSOEInfo)) {
//处理主动上送的波形文件信息报文
std::cout << "GET: MsgResponseType::Response_ActiveSOEInfo";
DIY_INFOLOG_CODE(id, 1, static_cast<int>(LogCode::LOG_CODE_TRANSIENT), "收到装置主动上送的暂态波形文件信息报文");
unsigned char file_type = udata[12];//录波文件类型数 cfg dat hdr 1-3
unsigned char line_id = udata[13];//录波测点 1-6
const uint8_t* data_ptr = parser.RecvData.data() + 2;//数据体去除前两位
@@ -398,6 +498,20 @@ void process_received_message(string mac, string id,const char* data, size_t len
// 这里可以添加处理主动上报数据的逻辑
break;
case DeviceState::HEART_BEAT:
//接收到心跳报文应答
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_HeartBeat)) {
std::cout << "heartbeat success" << mac << std::endl;
//心跳设置成功,调整为空闲,处理后续工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问异常
// 接收心跳报文错误,调整为空闲状态,处理下一项工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
break;
case DeviceState::READING_STATS:
// 读取统计数据状态
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Stat)) {
@@ -736,8 +850,8 @@ void process_received_message(string mac, string id,const char* data, size_t len
<< ", Error: " << strerror(errno) << std::endl;
// 文件保存失败,通知云端
/*on_device_response_minimal(static_cast<int>(ResponseCode::BAD_REQUEST),
id, 0, static_cast<int>(DeviceState::READING_EVENTFILE));*/
//on_device_response_minimal(static_cast<int>(ResponseCode::BAD_REQUEST),
// id, 0, static_cast<int>(DeviceState::READING_EVENTFILE));
}
//当前文件下载完毕,调整为空闲处理下一项工作(如果这里后续有新文件等待下载,一般已经存入等待队列等候处理了,调成空闲状态后直接就会开始新文件的下载工作)
@@ -793,6 +907,19 @@ void process_received_message(string mac, string id,const char* data, size_t len
// 处理完成后重置状态
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewNACK)) {
// 文件目录为空
std::cout << "*** empty ***! " << mac << std::endl;
//传入空的list表示目录为空
std::vector<tag_dir_info> FileList;
filemenu_cache_put(id,FileList);
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::READING_FILEMENU));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
std::cout << "reason code: " << static_cast<int>(udata[8]) << "-" << static_cast<int>(udata[9]) << "-" << static_cast<int>(udata[10]) << "-" << static_cast<int>(udata[11]) << std::endl;
// 装置答非所问异常
@@ -802,6 +929,166 @@ void process_received_message(string mac, string id,const char* data, size_t len
}
break;
case DeviceState::SEND_FILE:
//文件上送
if(udata[8] == static_cast<unsigned char>(MsgResponseType::Response_File_Send)){
//文件应答最后一帧后,再回复的结束帧
std::cout << "*** send file success ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::SEND_FILE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewACK)) {
uint32_t current_frame_index = 0; // 当前帧(下一次要发的帧号0-based)
uint32_t total_frames = 0; // 总帧数
bool all_sent = false; // 是否所有帧都已发出
std::vector<unsigned char> packet; // 下一帧报文
bool ok = ClientManager::instance().try_get_next_send_file_packet_to_device(
id,
current_frame_index,
total_frames,
all_sent,
packet
);
if (!ok) {
// 组装后续文件上送报文失败
std::cout << "*** send file get next packet fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::BAD_REQUEST), id, 0, static_cast<int>(DeviceState::SEND_FILE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (!packet.empty()) {
// 成功拿到下一帧,立即发送
std::cout << "已生成并发送下一帧文件上送报文,当前进度: "
<< current_frame_index << "/" << total_frames << std::endl;
// 和升级一样,直接切状态发送,避免被其他动作打断
ClientManager::instance().change_device_state(id, DeviceState::SEND_FILE, packet);
if (all_sent) {
std::cout << "最后一帧已发出,等待装置最终文件应答\n";
}
}
else if (all_sent) {
// 所有数据帧都已经发送完毕,此时等待 Response_File_Send 最终应答
std::cout << "所有文件帧都已发送完毕,等待装置最终文件应答\n";
return;
}
else {
// 理论上不应出现
std::cout << "*** send file invalid next packet ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SEND_FILE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewNACK)) {
// 当前帧被拒收,文件上送失败
std::cout << "*** send file 0x41 fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::FORBIDDEN), id, 0, static_cast<int>(DeviceState::SEND_FILE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问
std::cout << "*** send file ?? fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SEND_FILE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
break;
case DeviceState::DEL_FILE:
//文件删除
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewACK)) {
//文件删除完毕!
std::cout << "*** del file success ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::DEL_FILE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewNACK)) {
// 当前帧被拒收,文件删除失败
std::cout << "*** del file 0x41 fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::FORBIDDEN), id, 0, static_cast<int>(DeviceState::DEL_FILE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问
std::cout << "*** del file ?? fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::DEL_FILE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
break;
case DeviceState::SEND_MENU:
//创建目录
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewACK)) {
//创建目录完毕!
std::cout << "*** send menu success ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::SEND_MENU));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewNACK)) {
// 当前帧被拒收,创建目录失败
std::cout << "*** send menu 0x41 fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::FORBIDDEN), id, 0, static_cast<int>(DeviceState::SEND_MENU));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问
std::cout << "*** send menu ?? fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SEND_MENU));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
break;
case DeviceState::DEL_MENU:
//删除目录
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewACK)) {
//删除目录完毕!
std::cout << "*** del menu success ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::DEL_MENU));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewNACK)) {
// 当前帧被拒收,删除目录失败
std::cout << "*** del menu 0x41 fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::FORBIDDEN), id, 0, static_cast<int>(DeviceState::DEL_MENU));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问
std::cout << "*** del menu ?? fail ***! " << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::DEL_MENU));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
break;
case DeviceState::READING_FILEDATA:
//下载文件数据 和暂态文件下载共用同一功能码
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_File_Download))
@@ -878,45 +1165,49 @@ void process_received_message(string mac, string id,const char* data, size_t len
//调试用
// 若是 .cfg先查看并打印内容限长
{
auto dot = file_path.find_last_of('.');
std::string ext = (dot == std::string::npos) ? "" : file_path.substr(dot);
// 转小写比较
for (auto& c : ext) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
if (ext == ".cfg") {
std::ifstream fin(file_path, std::ios::binary);
if (!fin) {
std::cerr << "[CFG] open failed: " << file_path << " (" << std::strerror(errno) << ")\n";
} else {
// 读取前 8KB 作为预览,避免日志过大
constexpr size_t kMaxPreview = 8 * 1024;
std::string buf;
buf.resize(kMaxPreview);
fin.read(&buf[0], static_cast<std::streamsize>(kMaxPreview));
std::streamsize got = fin.gcount();
buf.resize(static_cast<size_t>(got));
{
auto dot = file_path.find_last_of('.');
std::string ext = (dot == std::string::npos) ? "" : file_path.substr(dot);
// 转小写比较
for (auto& c : ext) c = static_cast<char>(std::tolower(static_cast<unsigned char>(c)));
if (ext == ".cfg") {
std::ifstream fin(file_path, std::ios::binary);
if (!fin) {
std::cerr << "[CFG] open failed: " << file_path << " (" << std::strerror(errno) << ")\n";
} else {
// 读取前 8KB 作为预览,避免日志过大
constexpr size_t kMaxPreview = 8 * 1024;
std::string buf;
buf.resize(kMaxPreview);
fin.read(&buf[0], static_cast<std::streamsize>(kMaxPreview));
std::streamsize got = fin.gcount();
buf.resize(static_cast<size_t>(got));
std::cout << "================ [CFG PREVIEW BEGIN] ================\n";
std::cout << "path=" << file_path << ", size=" << file_data.size()
<< " bytes, preview=" << got << " bytes\n";
// 直接打印文本预览;如果包含不可见字符,会按原样输出
std::cout.write(buf.data(), static_cast<std::streamsize>(buf.size()));
if (static_cast<size_t>(got) == kMaxPreview && fin.peek() != EOF) {
std::cout << "\n...[truncated]\n";
}
std::cout << "\n================ [CFG PREVIEW END] ==================\n";
}
}
}
std::cout << "================ [CFG PREVIEW BEGIN] ================\n";
std::cout << "path=" << file_path << ", size=" << file_data.size()
<< " bytes, preview=" << got << " bytes\n";
// 直接打印文本预览;如果包含不可见字符,会按原样输出
std::cout.write(buf.data(), static_cast<std::streamsize>(buf.size()));
if (static_cast<size_t>(got) == kMaxPreview && fin.peek() != EOF) {
std::cout << "\n...[truncated]\n";
}
std::cout << "\n================ [CFG PREVIEW END] ==================\n";
}
}
}
//使用接口上送文件lnk20250826
std::string filename;
//SendFileWebAuto(id, file_path, file_path, filename);//如果是补招文件的下载,下载后也是直接上传,这样单纯补招波形也可以保证传文件
std::cout << "File download success wait for upload: " << filename << std::endl;
//通知文件上传
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::READING_FILEDATA));
if(SendFileWebAuto(id, file_path, file_path, filename)){//如果是补招文件的下载则不会在这边上送
std::cout << "File upload success: " << filename << std::endl;
//通知文件上传
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::READING_FILEDATA));
}
else{
on_device_response_minimal(static_cast<int>(ResponseCode::BAD_REQUEST), id, 0, static_cast<int>(DeviceState::READING_FILEDATA));
std::cerr << "File download success but upload failed: " << filename << std::endl;
}
}
else {
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::READING_FILEDATA));
@@ -1392,7 +1683,7 @@ void process_received_message(string mac, string id,const char* data, size_t len
std::string payload(payloadBytes.begin(), payloadBytes.end());
// 定义类似New_MachMessage的结构体
struct RunningInformation {
/*struct RunningInformation {
std::string Time;
std::string CpuLoad;
std::string FreeMemory;
@@ -1403,7 +1694,8 @@ void process_received_message(string mac, string id,const char* data, size_t len
std::string SntpTimeSync;
std::string CloudTimeSync;
std::string SignalStrength;
} result;
} result;*/
RunningInformation result;
// 辅助函数:去除字符串两端的引号
auto trimQuotes = [](const std::string& str) -> std::string {
@@ -1547,11 +1839,18 @@ void process_received_message(string mac, string id,const char* data, size_t len
<< ", Cloud=" << result.CloudTimeSync << "\n"
<< " Signal: " << result.SignalStrength << std::endl;
runninginfo_cache_put(id, result);
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::READING_RUNNINGINFORMATION_1));
//读取装置运行信息(主动触发)成功,调整为空闲,处理后续工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问异常
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::READING_RUNNINGINFORMATION_1));
// 读取装置运行信息(主动触发)失败,调整为空闲状态,处理下一项工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
@@ -1788,7 +2087,7 @@ void process_received_message(string mac, string id,const char* data, size_t len
std::string payload(payloadBytes.begin(), payloadBytes.end());
// 定义存储装置版本信息的结构体
struct DeviceVersionInfo {
/*struct DeviceVersionInfo {
std::string BaseModel; // 1: 装置基础型号
std::string CloudProtocolVer; // 2: 云服务协议版本
std::string AppVersion; // 3: 应用程序版本号
@@ -1816,7 +2115,8 @@ void process_received_message(string mac, string id,const char* data, size_t len
unsigned int CommProtocols = 0; // 51: 投入的通讯协议
unsigned int TimeSyncMethods = 0;// 52: 投入的对时方式
unsigned int DeviceFunctions = 0;// 53: 装置功能配置
} versionInfo;
} versionInfo;*/
DeviceVersionInfo versionInfo;
// 分割字段
std::vector<std::string> fields;
@@ -1922,11 +2222,15 @@ void process_received_message(string mac, string id,const char* data, size_t len
<< " Time Sync Methods: 0x" << versionInfo.TimeSyncMethods << "\n"
<< " Device Functions: 0x" << versionInfo.DeviceFunctions << std::dec << "\n";
versioninfo_cache_put(id, versionInfo);
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::READING_DEVVERSION));
//读取装置版本配置信息成功,调整为空闲,处理后续工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问异常
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::READING_DEVVERSION));
// 读取装置版本配置信息失败,调整为空闲状态,处理下一项工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
@@ -1959,6 +2263,9 @@ void process_received_message(string mac, string id,const char* data, size_t len
//设置装置对时(主动对时)
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewACK)) {
std::cout << "set success" << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::SET_RIGHTTIME_2));
//对时设置成功,调整为空闲,处理后续工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
@@ -1968,11 +2275,13 @@ void process_received_message(string mac, string id,const char* data, size_t len
std::cout << "reason code: " << static_cast<int>(udata[8]) << "-" << static_cast<int>(udata[9]) << "-" << static_cast<int>(udata[10]) << "-" << static_cast<int>(udata[11]) << std::endl;
// 装置否定应答,对时设置失败
on_device_response_minimal(static_cast<int>(ResponseCode::BAD_REQUEST), id, 0, static_cast<int>(DeviceState::SET_RIGHTTIME_2));
// 设置对时失败,调整为空闲状态,处理下一项工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问异常
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SET_RIGHTTIME_2));
// 设置对时失败,调整为空闲状态,处理下一项工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
@@ -2219,6 +2528,244 @@ void process_received_message(string mac, string id,const char* data, size_t len
}
break;
case DeviceState::SET_CTRL:
//装置控制命令
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Ctrl)) {
//第一次接收到控制命令应答,尝试校验命令是否合法!
if (udata[9] == 0x01) {
//当前仅检查0x01复位指令其余控制指令全部依照不合法处理
std::cout << "***ctrl do next" << mac << std::endl;
//校验完毕后直接准备重启
auto packet = generate_control_message(0x01, 0x01);
ClientManager::instance().change_device_state(id, DeviceState::SET_CTRL, packet);
}
else {
std::cout << "***ctrl fail" << mac << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::UNAUTHORIZED), id, 0, static_cast<int>(DeviceState::SET_CTRL));
//控制命令校验不合法,调整为空闲,处理后续工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewACK)) {
std::cout << "***ctrl success" << mac << std::endl;
//控制命令执行完毕,调整为空闲,处理后续工作。
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::SET_CTRL));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewNACK)) {
std::cout << "***ctrl fail" << mac << std::endl;
//控制命令执行失败,调整为空闲,处理后续工作。
on_device_response_minimal(static_cast<int>(ResponseCode::BAD_REQUEST), id, 0, static_cast<int>(DeviceState::SET_CTRL));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问异常
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SET_CTRL));
// 控制命令失败,调整为空闲状态,处理下一项工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
break;
case DeviceState::SET_PREUPGRADE:
//装置预升级校验
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Read_RunningInformation)) {
// 获取解析后的数据体
std::vector<uint8_t>& recvData = parser.RecvData;
// 检查数据长度是否足够
if (recvData.size() < 2) {
//装置上送的预校验文件异常!预校验失败!
std::cerr << "Invalid running information data: too short ("
<< recvData.size() << " bytes)" << std::endl;
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
break;
}
// 提取有效载荷长度
size_t payloadLength = recvData.size() - 2;
// 复制有效载荷数据
std::vector<uint8_t> payloadBytes(payloadLength);
if (recvData.size() >= 2 + payloadLength) {
std::copy(recvData.begin() + 2, recvData.begin() + 2 + payloadLength, payloadBytes.begin());
}
else {
//装置上送的预校验文件异常!预校验失败!
std::cerr << "Invalid payload length: " << payloadLength
<< ", available: " << (recvData.size() - 2) << std::endl;
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
break;
}
// payload 至少要有 4 个字节,才能取前四位作为 32 位整数
if (payloadBytes.size() < 4) {
//装置上送的预校验文件异常!预校验失败!
std::cerr << "Invalid payloadBytes: too short to extract int32 ("
<< payloadBytes.size() << " bytes)" << std::endl;
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
break;
}
// 取前 4 个字节并转换为 32 位整数(按大端序)
int32_t dataLength =
(static_cast<int32_t>(payloadBytes[0]) << 24) |
(static_cast<int32_t>(payloadBytes[1]) << 16) |
(static_cast<int32_t>(payloadBytes[2]) << 8) |
(static_cast<int32_t>(payloadBytes[3]));
// 去掉前 4 个字节,取出剩余部分
std::vector<uint8_t> realPayload(payloadBytes.begin() + 4, payloadBytes.end());
// 检查剩余部分长度是否与前面的 32 位整数一致
if (dataLength < 0 || realPayload.size() != static_cast<size_t>(dataLength)) {
std::cerr << "Payload length mismatch: expected " << dataLength
<< ", actual " << realPayload.size() << std::endl;
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
break;
}
// 到这里说明:
// 1. 前4字节已经解析成 int32_t dataLength
// 2. 剩余数据保存在 realPayload 中
// 3. realPayload.size() == dataLength
std::cout << "********* wait crc *********" << std::endl;
// 用前4字节生成本地“标准文件内容”
std::vector<uint8_t> localFile = GeneratePreUpgradeFileFromLengthBytes(dataLength);
// 计算 CRC
uint32_t crc = CalcNormalCrc32(realPayload, 0x04C11DB7u);
uint32_t generatedCrc = CalcNormalCrc32(localFile, 0x04C11DB7u);
std::cout << "Generated CRC = 0x" << std::hex << std::uppercase << generatedCrc << std::endl;
std::cout << "Received CRC = 0x" << std::hex << std::uppercase << crc << std::endl;
std::cout << std::dec;
if (generatedCrc != crc) {
//crc 校验失败 后续升级停止!
std::cerr << "CRC verify failed." << std::endl;
on_device_response_minimal(static_cast<int>(ResponseCode::UNAUTHORIZED), id, 0, static_cast<int>(DeviceState::SET_PREUPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
break;
}
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::SET_PREUPGRADE));
// 预升级校验结束成功,调整为空闲,处理后续工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问异常
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SET_PREUPGRADE));
// 预升级校验失败,调整为空闲状态,处理下一项工作。
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
break;
case DeviceState::SET_UPGRADE:
//装置升级
if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_Upgrade)) {
//接收到最终的升级验证报文
if (udata[9] == 0x01) {
//接收文件成功,下发开始升级指令
//事件不插入队列,直接修改装置最新状态,防止外部其他指令打断更新流程
std::cout << "*** upgrade 0x01 do next ***!" << mac << std::endl;
auto sendbuff = generate_upgrade_end_message();
ClientManager::instance().change_device_state(id, DeviceState::SET_UPGRADE, sendbuff);
}
else if (udata[9] == 0x02) {
//接收文件错误!
std::cout << "*** upgrade 0x02 fail ***!" << mac << std::endl;
// 升级流程失败,调整为空闲状态,处理下一项工作。
on_device_response_minimal(static_cast<int>(ResponseCode::NOT_FOUND), id, 0, static_cast<int>(DeviceState::SET_PREUPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (udata[9] == 0x55) {
//升级流程成功,等候装置重启
std::cout << "*** upgrade 0x55 success ***!" << mac << std::endl;
// 升级流程成功,调整为空闲状态,处理下一项工作。
on_device_response_minimal(static_cast<int>(ResponseCode::OK), id, 0, static_cast<int>(DeviceState::SET_PREUPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (udata[9] == 0xAA) {
// 升级流程失败!
std::cout << "*** upgrade 0xAA fail ***!" << mac << std::endl;
// 升级流程失败,调整为空闲状态,处理下一项工作。
on_device_response_minimal(static_cast<int>(ResponseCode::BAD_REQUEST), id, 0, static_cast<int>(DeviceState::SET_PREUPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
std::cout << "*** upgrade ?? error ***!" << mac << std::endl;
// 升级流程失败,调整为空闲状态,处理下一项工作。
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SET_PREUPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewACK)) {
uint32_t current_frame_index = 0;//当前帧
uint32_t total_frames = 0;//总帧数
bool all_sent = false;
std::vector<unsigned char> packet;//报文流
bool ok = ClientManager::instance().try_get_next_upgrade_packet_to_device(
id,
current_frame_index,
total_frames,
all_sent,
packet
);
if (!ok) {
//组装后续升级报文时出现异常,无法发送后续帧文件
std::cout << "获取下一帧失败\n";
on_device_response_minimal(static_cast<int>(ResponseCode::NOT_FOUND), id, 0, static_cast<int>(DeviceState::SET_UPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else if (!packet.empty()) {
// 只要拿到了报文,就先发送
std::cout << "已生成并发送下一帧,当前进度: "
<< current_frame_index << "/" << total_frames << std::endl;
ClientManager::instance().change_device_state(id, DeviceState::SET_UPGRADE, packet);
if (all_sent) {
std::cout << "最后一帧已发出,后续等待装置消息\n";
}
}
else if (all_sent) {
// 没有新报文可发,说明之前已经全部发完
std::cout << "所有帧都已发送完毕,等待装置消息\n";
return;
}
else {
// 理论上不该走到这里,防御处理
std::cout << "未获取到有效升级报文\n";
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SET_UPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
}
else if (udata[8] == static_cast<unsigned char>(MsgResponseType::Response_NewNACK)) {
std::cout << "*** upgrade 0x41 fail ***!" << mac << std::endl;
// 升级流程失败,调整为空闲状态,处理下一项工作。
on_device_response_minimal(static_cast<int>(ResponseCode::BAD_REQUEST), id, 0, static_cast<int>(DeviceState::SET_PREUPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
else {
// 装置答非所问异常
std::cout << "*** upgrade ?? fail ***!" << mac << std::endl;
// 升级流程失败,调整为空闲状态,处理下一项工作。
on_device_response_minimal(static_cast<int>(ResponseCode::INTERNAL_ERROR), id, 0, static_cast<int>(DeviceState::SET_UPGRADE));
ClientManager::instance().change_device_state(id, DeviceState::IDLE);
}
break;
case DeviceState::CUSTOM_ACTION:
// 自定义动作状态
std::cout << "CUSTOM_ACTION state: Processing custom response from " << mac << std::endl;

View File

@@ -7,6 +7,7 @@
#include "client2.h"
#include "cloudfront/code/interface.h"
#include "pqdif_thread_processor.h"
#include <iostream>
#include <thread>
#include <chrono>
@@ -35,7 +36,7 @@ typedef struct {
#endif
extern std::atomic<int> INITFLAG;//̨<>˵ȳ<CBB5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD>־
//extern void cleanup_args(ThreadArgs* args);
//extern void cleanup_args(ThreadArgs* args);00:B7:8D:A8:00:D6 00:B7:8D:00:A9:03
void init_daemon(void)
{
@@ -66,53 +67,9 @@ void init_daemon(void)
thread_info_t thread_info[THREAD_CONNECTIONS]; // <20>߳<EFBFBD><DFB3><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
pthread_mutex_t global_lock = PTHREAD_MUTEX_INITIALIZER; // ȫ<>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD>
extern SafeMessageQueue message_queue;
// <20><><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>װ<EFBFBD><EFBFBD>
std::vector<DeviceInfo> generate_test_devices(int count) {
std::vector<DeviceInfo> devices;
for (int i = 1; i <= count; ++i) {
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>ID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::string dev_id = "D" + std::to_string(1000 + i).substr(1); // D001, D002, ..., D100
std::string dev_name = "Device " + std::to_string(i);
// <20><><EFBFBD>ɲ<EFBFBD><C9B2><EFBFBD>
std::vector<PointInfo> points = {
{
"P" + dev_id.substr(1) + "01", // <20><><EFBFBD><EFBFBD>ID<49><44> P00101
"Voltage " + dev_name,
dev_id,
1,
0.0, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹֵ
0.0,
100.0,
80.0
},
{
"P" + dev_id.substr(1) + "02", // <20><><EFBFBD><EFBFBD>ID<49><44> P00102
"Current " + dev_name,
dev_id,
2,
0.0, // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ
0.0,
20.0,
15.0
}
};
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>
devices.push_back({
dev_id,
dev_name,
(i % 2 == 0) ? "Model-X" : "Model-Y", // <20><><EFBFBD><EFBFBD>ʹ<EFBFBD><CAB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͺ<EFBFBD>
"00-B7-8D-A8-00-D6", // <20><><EFBFBD><EFBFBD>MAC<41><43>ַ
1, // ״̬ (1=<3D><><EFBFBD><EFBFBD>)
points
});
}
return devices;
}
bool PQD_FLAG = false;//pqd<71>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־ <20>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><D8B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>й<EFBFBD><D0B9><EFBFBD><EFBFBD>߳<EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD><E2B2BF><EFBFBD><EFBFBD>
//̨<>˴<EFBFBD>ӡ
void PrintDevices(const std::vector<DeviceInfo>& devices) {
std::cout << "==== Devices List (" << devices.size() << ") ====\n";
for (const auto& dev : devices) {
@@ -139,7 +96,7 @@ void PrintDevices(const std::vector<DeviceInfo>& devices) {
}
}
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 0<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
/* <20>ͻ<EFBFBD><CDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӹ<EFBFBD><D3B9><EFBFBD><EFBFBD>̺߳<DFB3><CCBA><EFBFBD>*/
void* client_manager_thread(void* arg) {
int index = *(int*)arg;
@@ -171,9 +128,6 @@ void* client_manager_thread(void* arg) {
// }
//};
// <20><><EFBFBD><EFBFBD>100<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>
//std::vector<DeviceInfo> test_devices = generate_test_devices(100);
//lnk<6E><6B>̨<EFBFBD>˶<EFBFBD>ȡ<EFBFBD>
std::vector<DeviceInfo> devices = GenerateDeviceInfoFromLedger(terminal_devlist);//lnk<6E><6B><EFBFBD><EFBFBD>
@@ -192,7 +146,7 @@ void* client_manager_thread(void* arg) {
pthread_mutex_unlock(&thread_info[index].lock);
return NULL;
}
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
/* <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>̺߳<DFB3><CCBA><EFBFBD> */
void* message_processor_thread(void* arg) {
int index = *(int*)arg;
@@ -230,6 +184,39 @@ void* message_processor_thread(void* arg) {
pthread_mutex_unlock(&thread_info[index].lock);
return NULL;
}
/* <20>̹߳<DFB3><CCB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 3<><33><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>*/
/* PQDIF<49><46><EFBFBD><EFBFBD><EFBFBD>̺߳<DFB3><CCBA><EFBFBD>*/
void* pqd_thread(void* arg)
{
int index = *(int*)arg;
free(arg);
pthread_mutex_lock(&thread_info[index].lock);
printf("PQDIF Thread %d started\n", index);
thread_info[index].state = THREAD_RUNNING;
pthread_mutex_unlock(&thread_info[index].lock);
try
{
// <20><><EFBFBD><EFBFBD> PQDIF ɨ<><C9A8><EFBFBD>߳<EFBFBD>
RunPqdifScanLoop();
}
catch (const std::exception& ex)
{
printf("PQDIF Thread %d exception: %s\n", index, ex.what());
}
catch (...)
{
printf("PQDIF Thread %d exception: unknown\n", index);
}
pthread_mutex_lock(&thread_info[index].lock);
thread_info[index].state = THREAD_STOPPED;
printf("PQDIF Thread %d stopped\n", index);
pthread_mutex_unlock(&thread_info[index].lock);
return NULL;
}
/* <20>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
void restart_thread(int index) {
@@ -270,7 +257,7 @@ void restart_thread(int index) {
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
}
} else if (index == 1) {
} else if (index == 1 && !PQD_FLAG) {
// <20>ͻ<EFBFBD><CDBB>˹<EFBFBD><CBB9><EFBFBD><EFBFBD>߳<EFBFBD>
int* new_index = (int*)malloc(sizeof(int));
if (!new_index) {
@@ -282,15 +269,14 @@ void restart_thread(int index) {
}
*new_index = index;
if (pthread_create(&thread_info[index].tid, NULL,
client_manager_thread, new_index) != 0) {
if (pthread_create(&thread_info[index].tid, NULL,client_manager_thread, new_index) != 0) {
pthread_mutex_lock(&global_lock);
printf("Failed to restart client manager thread %d\n", index);
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
free(new_index); // ʧ<>ܲ<EFBFBD><DCB2>Լ<EFBFBD> free<65><65><EFBFBD>ɹ<EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD>߳<EFBFBD><DFB3><EFBFBD> free
}
} else if (index == 2) {
} else if (index == 2 && !PQD_FLAG) {
// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
int* new_index = (int*)malloc(sizeof(int));
if (!new_index) {
@@ -302,61 +288,36 @@ void restart_thread(int index) {
}
*new_index = index;
if (pthread_create(&thread_info[index].tid, NULL,
message_processor_thread, new_index) != 0) {
if (pthread_create(&thread_info[index].tid, NULL,message_processor_thread, new_index) != 0) {
pthread_mutex_lock(&global_lock);
printf("Failed to restart message processor thread %d\n", index);
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
free(new_index);
}
} else if(index == 3 && PQD_FLAG){
//PQDIF<49><46><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> <20><><EFBFBD><EFBFBD><E0B9A4><EFBFBD>̲߳<DFB3><CCB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int* new_index = (int*)malloc(sizeof(int));
if (!new_index) {
pthread_mutex_lock(&global_lock);
printf("Failed to malloc for message processor thread %d\n", index);
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
return;
}
*new_index = index;
if (pthread_create(&thread_info[index].tid, NULL, pqd_thread, new_index) != 0) {
pthread_mutex_lock(&global_lock);
printf("Failed to restart message processor thread %d\n", index);
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
free(new_index);
}
} else {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><DFB3>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD>
}
/*// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
int* new_index = (int*)malloc(sizeof(int));
*new_index = index;
if (index == 1) {
// <20>ͻ<EFBFBD><CDBB>˹<EFBFBD><CBB9><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[index].tid, NULL, client_manager_thread, new_index) != 0) {
pthread_mutex_lock(&global_lock);
printf("Failed to restart client manager thread %d\n", index);
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
free(new_index);
}
}
else if (index == 2) {
// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[index].tid, NULL, message_processor_thread, new_index) != 0) {
pthread_mutex_lock(&global_lock);
printf("Failed to restart message processor thread %d\n", index);
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
free(new_index);
}
}
else if (index == 0) {
// <20>ӿڣ<D3BF>mq
//char* argv[] = { (char*)new_index };//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺Ų<CCBA><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ThreadArgs* args = new ThreadArgs{1, argv};
if (pthread_create(&thread_info[index].tid, NULL, cloudfrontthread, new_index) != 0) {
pthread_mutex_lock(&global_lock);
printf("Failed to restart message processor thread %d\n", index);
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
//delete args; // <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6>ͷ<EFBFBD>
free(new_index);
}
}
else {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>գ<EFBFBD>ʵ<EFBFBD><CAB5>Ӧ<EFBFBD><D3A6><EFBFBD>п<EFBFBD><D0BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
}*/
}
/* <20>̴߳<DFB3><CCB4><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
@@ -364,16 +325,6 @@ int is_thread_alive(pthread_t tid) {
return pthread_tryjoin_np(tid, NULL) == EBUSY; // EBUSY<53><59>ʾ<EFBFBD>߳<EFBFBD><DFB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
//lnk<6E><6B><EFBFBD><EFBFBD>
/*ThreadArgs* make_thread_args_from_strs(const std::vector<std::string>& args_vec) {
char** argv = new char*[args_vec.size() + 1]; // <20><>һ<EFBFBD><D2BB> nullptr <20><>β
for (size_t i = 0; i < args_vec.size(); ++i) {
argv[i] = strdup(args_vec[i].c_str()); // strdup <20><> malloc <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
argv[args_vec.size()] = nullptr;
return new ThreadArgs{static_cast<int>(args_vec.size()), argv};
}*/
/* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> */
int main(int argc ,char** argv) {//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӳ<EFBFBD><D3B2><EFBFBD>
if(!parse_param(argc,argv)){
@@ -407,29 +358,26 @@ int main(int argc ,char** argv) {//
int* index = (int*)malloc(sizeof(int));
*index = i;
if (i == 1) {
if (i == 1 && !PQD_FLAG) {
// <20>ͻ<EFBFBD><CDBB>˹<EFBFBD><CBB9><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[i].tid, NULL, client_manager_thread, index) != 0) {
if (pthread_create(&thread_info[i].tid, NULL, client_manager_thread, index) != 0 ) {
printf("Failed to create client manager thread %d\n", i);
free(index);
}
}
else if (i == 2) {
else if (i == 2 && !PQD_FLAG) {
// <20><>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[i].tid, NULL, message_processor_thread, index) != 0) {
if (pthread_create(&thread_info[i].tid, NULL, message_processor_thread, index) != 0 ) {
printf("Failed to create message processor thread %d\n", i);
free(index);
}
}
else if (i == 3){
/*//<2F>ӿں<D3BF>mq
char* argv[] = { (char*)index };//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>̺Ų<CCBA><C5B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ThreadArgs* args = new ThreadArgs{1, argv};
if (pthread_create(&thread_info[i].tid, NULL, cloudfrontthread, args) != 0) {
printf("Failed to create message processor thread %d\n", i);
delete args; // <20><><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD><EFBFBD>ɹ<EFBFBD><C9B9><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6>ͷ<EFBFBD>
else if (i == 3 && PQD_FLAG){
//PQDIF<49><46><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><E0B9A4><EFBFBD>߳<EFBFBD>ֹͣ
if (pthread_create(&thread_info[i].tid, NULL, pqd_thread, index) != 0) {
printf("Failed to create pqd_thread %d\n", i);
free(index);
}*/
}
}
else {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
@@ -465,59 +413,12 @@ int main(int argc ,char** argv) {//
}
}
/*// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::vector<PointInfo> points2 = {
{"P101", "Generator Output", "D002",1 ,1, 1, 1, 1,"0.38k",0}
};
//00B78DA800D6 00-B7-8D-01-79-06 00-B7-8D-A8-00-D6
// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>б<EFBFBD>
std::vector<DeviceInfo> devices = {
{
"D002", "Backup Device", "Model-Y", "00-B7-8D-A8-00-D6",
1, points2,true
}
};*/
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//std::vector<PointInfo> points1 = {
// {"P001", "Main Voltage", "D001",1 ,1, 1, 1, 1,"0.38k",0},
// {"P002", "Backup Voltage", "D001",2 ,1, 1, 1, 1,"0.38k",0}
//};
//std::vector<PointInfo> points2 = {
// {"P003", "Main Voltage", "D002",1 ,1, 1, 1, 1,"0.38k",0},
// {"P004", "Backup Voltage", "D002",2 ,1, 1, 1, 1,"0.38k",0}
//};
////00B78DA800D6 00-B7-8D-01-79-06 00-B7-8D-A8-00-D6 00-B7-8D-01-71-09 00-B7-8D-01-88-7f
//// <20><><EFBFBD><EFBFBD>װ<EFBFBD><D7B0><EFBFBD>б<EFBFBD>
//std::vector<DeviceInfo> devices = {
// {
// "D001", "Primary Device", "Model-X", "00-B7-8D-01-88-7f",
// 1, points1,true
// },
// {
// "D002", "Primary Device1", "Model-X1", "00-B7-8D-01-71-09",
// 1, points2,true
// }
//};
// <20><><EFBFBD><EFBFBD>socket<65><74><EFBFBD><EFBFBD>״̬
static int queue_monitor = 0;
static bool flag = false;
//static int count = 3;
if (++queue_monitor >= 60) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>
if (++queue_monitor >= 60) {
printf("Message queue size: %zu\n", message_queue.size());
queue_monitor = 0;
/*if (flag) {
flag = false;
for (const auto& device : devices) {
ClientManager::instance().add_device(device);
}
}
else {
flag = true;
ClientManager::instance().remove_device("D001");
ClientManager::instance().remove_device("D002");
}*/
}
}

1585
LFtid1056/pqdif/PQDIF.cpp Normal file

File diff suppressed because it is too large Load Diff

194
LFtid1056/pqdif/PQDIF.h Normal file
View File

@@ -0,0 +1,194 @@
#pragma once
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctime>
#include <list>
#include <map>
#include "cjson.h"
#include "PQDIF_classes.h"
#include "pqdif_ph.h"
typedef double DATE;
class CPQDIF_Element;
class CPQDIF_E_Collection;
class CPQDIF_E_Scalar;
class CPQDIF_E_Vector;
class CPQDIF_R_Observation;
class CPQDIF_R_DataSource;
class CPQDIF_R_Container;
class CPQDIF_R_Settings;
class CPQDIF_PC_FlatFile;
// ============================
// PQDIF ͨ<><CDA8><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>Ϣ
// <20><><EFBFBD>ã<EFBFBD><C3A3>ѱ<EFBFBD>׼<EFBFBD><D7BC><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǩ<EFBFBD><C7A9><EFBFBD><C2B6><EFBFBD>ϲ<EFBFBD>
// ============================
struct PqdifChannelInfoEx
{
std::string name; // ԭʼ tagChannelName
long countSeries = 0; // ͨ<><CDA8><EFBFBD>µ<EFBFBD> series <20><><EFBFBD><EFBFBD>
long phaseId = -1; // tagPhaseID
GUID quantityTypeId{}; // tagQuantityTypeID
long quantityMeasuredId = -1; // tagQuantityMeasuredID
};
// ============================
// PQDIF ϵ<><CFB5><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>Ϣ
// <20><><EFBFBD>ã<EFBFBD><C3A3>ѱ<EFBFBD>׼<EFBFBD><D7BC><EFBFBD><EFBFBD>ϵ<EFBFBD>м<EFBFBD><D0BC><EFBFBD>ǩ<EFBFBD><C7A9><EFBFBD><C2B6><EFBFBD>ϲ<EFBFBD>
// ============================
struct PqdifSeriesInfoEx
{
long quantityUnitsId = -1; // tagQuantityUnitsID
GUID quantityCharacteristicId{}; // tagQuantityCharacteristicID
GUID valueTypeId{}; // tagValueTypeID
long seriesBaseType = -1; // series <20>ײ<EFBFBD><D7B2><EFBFBD><EFBFBD>ͣ<EFBFBD><CDA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2>
double scale = 1.0; // <20><><EFBFBD><EFBFBD>ϵ<EFBFBD><CFB5>
double offset = 0.0; // ƫ<><C6AB>
};
class CPQDIF
{
public:
CPQDIF();
~CPQDIF();
public:
void GetTime(DATE dt, time_t* tm);
void put_FlatFileName(string strFileName);
bool Read();
bool Close();
bool New();
long RecordGetCount();
bool RecordGetInfo
(
long index,
GUID* tagRecordType,
string& nameRecordType
);
bool RecordRequestRecord(long index, long* pRecord);
bool RecordRequestObservation(long index, long* pRecordObserv);
bool ObservationGetInfo(long pRecordObserv, DATE& timeStart, string& name, long& countChannels);
bool ObservationGetTriggerInfo(long pRecordObserv, long* idTriggerMethod, DATE* timeTriggered);
bool ObservationGetChannelInfo(long pRecordObserv, long idxChannel, string& name, long* countSeries);
bool ObservationGetSeriesInfo3(long pRecordObserv, long idxChannel, long idxSeries, long* idQuantityUnits, GUID* idQuantityCharacteristic, GUID* idValueType);
bool ObservationGetSeriesData(long pRecordObserv, long idxChannel, long idxSeries, double** values, long* varCount);
bool ObservationGetChannelFreq(long pRecObs, long idxChannel, double* freq);
bool ObservationGetChannelGroupID(long pRecObs, long idxChannel, int* GroupID);
bool ObservationGetSeriesPhasicType(long pRecordObserv, long idxChannel, long idxSeries, long* valuetypes);
bool ObservationGetSeriesScale(long pRecObs, long idxChannel, long idxSeries, double* scale, double* offset);
bool RecordReleaseObservation(long pRecordObserv);
// <20><>ȡ Observation <20><>ij<EFBFBD><C4B3>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>ǩ<EFBFBD><C7A9>Ϣ
bool ObservationGetChannelInfoEx(long pRecordObserv, long idxChannel, PqdifChannelInfoEx* out);
// <20><>ȡ Observation <20><>ij<EFBFBD><C4B3> series <20><><EFBFBD><EFBFBD>չ<EFBFBD><D5B9>ǩ<EFBFBD><C7A9>Ϣ
bool ObservationGetSeriesInfoEx(long pRecordObserv, long idxChannel, long idxSeries, PqdifSeriesInfoEx* out);
// Internal
protected:
CPQDIF_Element* ValidateElement(long pElement);
CPQDIF_E_Collection* ValidateCollection(long pElement);
CPQDIF_E_Scalar* ValidateScalar(long pElement);
CPQDIF_E_Vector* ValidateVector(long pElement);
CPQDIF_R_Observation* ValidateObservation(long pRecObserv);
CPQDIF_R_DataSource* ValidateDataSource(long pRecDS);
CPQDIF_R_Settings* ValidateSettings(long pRecSettings);
CPQDIF_R_Container* ValidateContainer(long pRecCon);
bool SetDateFromTimeStamp(DATE& date, const TIMESTAMPPQDIF& ts);
// Member data
private:
CPQDIF_PC_FlatFile* m_percont; // Persistence controller
};
class CItem //<2F><><EFBFBD><EFBFBD><EFBFBD>¸<EFBFBD><C2B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խṹ
{
public:
string KeyName;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
string DateName;//<2F><><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD>
string Type;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> MAX MIN AVG CP95 NULL
CItem(const string& kn, const string& dn, const string& tp)
: KeyName(kn), DateName(dn), Type(tp) {}
};
class CSeq //<2F><><EFBFBD>¸<EFBFBD><C2B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
public:
string seq;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
string telemetryType;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>־
string jsonname;//josn key<65><79><EFBFBD><EFBFBD>
list<CItem*> DateItemList;//<2F><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
CSeq(const string& s, const string& tt, const string& tp)
: seq(s), telemetryType(tt), jsonname(tp) {}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
~CSeq() {
// <20>ͷ<EFBFBD>DateItemList<73>е<EFBFBD>CItem<65><6D><EFBFBD><EFBFBD>
for (std::list<CItem*>::iterator it = DateItemList.begin(); it != DateItemList.end(); ++it) {
delete* it; // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
}
DateItemList.clear(); // <20><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>е<EFBFBD>ָ<EFBFBD><D6B8>
}
};
class CTable //Ŀ<><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
{
public:
string TableName;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
list<CSeq*> DateSeqList;//<2F><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD>
CTable(const string& tn)
: TableName(tn) {}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
~CTable() {
// <20>ͷ<EFBFBD>DateSeqList<73>е<EFBFBD>CSeq<65><71><EFBFBD><EFBFBD>
for (std::list<CSeq*>::iterator it = DateSeqList.begin(); it != DateSeqList.end(); ++it) {
delete* it; // <20>ͷ<EFBFBD><CDB7>ڴ<EFBFBD>
}
DateSeqList.clear(); // <20><><EFBFBD><EFBFBD><EFBFBD>б<EFBFBD><D0B1>е<EFBFBD>ָ<EFBFBD><D6B8>
}
};
class CDeal //<2F><><EFBFBD>ݴ<EFBFBD><DDB4><EFBFBD><EFBFBD><EFBFBD>
{
public:
void clear();
void CheckDataTableList();//<2F><><EFBFBD><EFBFBD>DataTableList<73><74><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void ResJsonCfg(char* json);//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>json<6F><EFBFBD><E1B9B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
char* AssJson(char* Id);//<2F><>װjson<6F>ַ<EFBFBD><D6B7><EFBFBD>
cJSON* cJSON_GetObjectItemCaseSensitive(cJSON* object, const char* string);//json<6F><EFBFBD><E1B9B9><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ȡֵ
bool ExtractNumbersBetweenPercent(const std::string& str, int& start, int& end);
std::string convertToDateOnly(const std::string& dateTime);
int getCurrentGroup(const std::time_t& currentTime, int min);
std::time_t stringToTimeT(const std::string& dateTime);
std::list<CTable*> DataTableList;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ<EFBFBD><CFA2><EFBFBD><EFBFBD>
std::string MonitorId;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ID
std::string dataDate;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1>
std::string dataDatePT;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>
int ShortFlag = 0;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
int LongFlag = 0;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
int FluFlag = 0;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8>
int aggCydeMin = 3;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ĭ<><C4AC>Ϊ3
int fluCydeMin = 10;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ĭ<><C4AC>Ϊ10
int aggCycleMinShort = 10;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ĭ<><C4AC>Ϊ10
int aggCycleMinLong = 120;//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> Ĭ<><C4AC>Ϊ120
std::map< std::string, std::list<double> > AvgData;//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ݴ洢<DDB4><E6B4A2><EFBFBD><EFBFBD> avg<76><67><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::map< std::string, std::list<double> > MaxData;//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ݴ洢<DDB4><E6B4A2><EFBFBD><EFBFBD> Max<61><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::map< std::string, std::list<double> > MinData;//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ݴ洢<DDB4><E6B4A2><EFBFBD><EFBFBD> Min<69><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::map< std::string, std::list<double> > CP95Data;//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ݴ洢<DDB4><E6B4A2><EFBFBD><EFBFBD> CP95<39><35><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::map< std::string, std::list<double> > ValData;//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>ݴ洢<DDB4><E6B4A2><EFBFBD><EFBFBD> value<75><65><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::map< std::string, std::list<double> > TimeData;//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::map< std::string, std::string > DateData;//<2F><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD> <20><>ʼʱ<CABC><CAB1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
std::map< std::string, int > aggCydeMinList;
};
void testjson();

View File

@@ -0,0 +1,208 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="15.0" 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>15.0</VCProjectVersion>
<ProjectGuid>{0BB14D2D-2917-46AD-8E82-F0F7F5143CA4}</ProjectGuid>
<RootNamespace>PQDIFLib</RootNamespace>
<WindowsTargetPlatformVersion>10.0.17763.0</WindowsTargetPlatformVersion>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>true</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<CharacterSet>MultiByte</CharacterSet>
<UseOfMfc>Static</UseOfMfc>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v141</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
<UseOfMfc>Static</UseOfMfc>
</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 />
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>Disabled</Optimization>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>_MBCS;WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
</Link>
<Lib>
<OutputFile>E:\同步盘\源码\电压暂降高级算法\Linux\PQDIFDLLqt编译张文\PQDIFDLL\PQDIFDLL\lib\PQDIFLibd.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
</Link>
</ItemDefinitionGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<Optimization>MaxSpeed</Optimization>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<ConformanceMode>true</ConformanceMode>
<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<OutputFile>E:\同步盘\源码\电压暂降高级算法\Linux\PQDIFDLLqt编译张文\PQDIFDLL\PQDIFDLL\lib\PQDIFLib.lib</OutputFile>
</Link>
<Lib>
<AdditionalDependencies>%(AdditionalDependencies)</AdditionalDependencies>
<OutputFile>E:\同步盘\源码\电压暂降高级算法\Linux\PQDIFDLLqt编译张文\PQDIFDLL\PQDIFDLL\lib\PQDIFLib.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
<ClInclude Include="el_base.h" />
<ClInclude Include="el_coll.h" />
<ClInclude Include="el_scal.h" />
<ClInclude Include="el_vect.h" />
<ClInclude Include="pcn_base.h" />
<ClInclude Include="pcn_flat.h" />
<ClInclude Include="pqbytearray.h" />
<ClInclude Include="pqdfacty.h" />
<ClInclude Include="PQDIF_classes.h" />
<ClInclude Include="pqdif_custom_1.h" />
<ClInclude Include="pqdif_custom_2.h" />
<ClInclude Include="pqdif_id.h" />
<ClInclude Include="pqdif_lg.h" />
<ClInclude Include="pqdif_ph.h" />
<ClInclude Include="pqdinfo.h" />
<ClInclude Include="pqdsupport.h" />
<ClInclude Include="pqptrarray.h" />
<ClInclude Include="proc_bas.h" />
<ClInclude Include="proc_not.h" />
<ClInclude Include="proc_zlib.h" />
<ClInclude Include="rec_base.h" />
<ClInclude Include="rec_container.h" />
<ClInclude Include="rec_datasource.h" />
<ClInclude Include="rec_general.h" />
<ClInclude Include="rec_observ.h" />
<ClInclude Include="rec_settings.h" />
<ClInclude Include="ser_alloc.h" />
<ClInclude Include="ser_cont_el.h" />
<ClInclude Include="ser_iter_el.h" />
<ClInclude Include="str_base.h" />
<ClInclude Include="str_chnk.h" />
<ClInclude Include="str_flat.h" />
<ClInclude Include="zconf.h" />
<ClInclude Include="zlib.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="el_base.cpp" />
<ClCompile Include="el_coll.cpp" />
<ClCompile Include="el_scal.cpp" />
<ClCompile Include="el_vect.cpp" />
<ClCompile Include="pcn_base.cpp" />
<ClCompile Include="pcn_flat.cpp" />
<ClCompile Include="pqbytearray.cpp" />
<ClCompile Include="pqdfacty.cpp" />
<ClCompile Include="pqdinfo.cpp" />
<ClCompile Include="pqdsupport.cpp" />
<ClCompile Include="pqptrarray.cpp" />
<ClCompile Include="proc_bas.cpp" />
<ClCompile Include="proc_not.cpp" />
<ClCompile Include="proc_zlib.cpp" />
<ClCompile Include="rec_base.cpp" />
<ClCompile Include="rec_container.cpp" />
<ClCompile Include="rec_datasource.cpp" />
<ClCompile Include="rec_general.cpp" />
<ClCompile Include="rec_observ.cpp" />
<ClCompile Include="rec_settings.cpp" />
<ClCompile Include="ser_alloc.cpp" />
<ClCompile Include="ser_cont_el.cpp" />
<ClCompile Include="ser_iter_el.cpp" />
<ClCompile Include="str_base.cpp" />
<ClCompile Include="str_chnk.cpp" />
<ClCompile Include="str_flat.cpp" />
</ItemGroup>
<ItemGroup>
<None Include="..\build-ubuntu.sh" />
<None Include="..\Makefile" />
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
<ImportGroup Label="ExtensionTargets">
</ImportGroup>
</Project>

View File

@@ -0,0 +1,205 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="源文件">
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
</Filter>
<Filter Include="头文件">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hh;hpp;hxx;hm;inl;inc;ipp;xsd</Extensions>
</Filter>
<Filter Include="资源文件">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="el_base.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="el_coll.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="el_scal.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="el_vect.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="pcn_base.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="pcn_flat.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="pqbytearray.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="pqdfacty.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="pqdinfo.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="pqdsupport.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="pqptrarray.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="proc_bas.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="proc_not.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="proc_zlib.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="rec_base.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="rec_container.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="rec_datasource.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="rec_general.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="rec_observ.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="rec_settings.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="ser_alloc.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="ser_cont_el.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="ser_iter_el.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="str_base.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="str_chnk.cpp">
<Filter>源文件</Filter>
</ClCompile>
<ClCompile Include="str_flat.cpp">
<Filter>源文件</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="el_base.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="el_coll.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="el_scal.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="el_vect.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pcn_base.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pcn_flat.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqbytearray.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqdfacty.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="PQDIF_classes.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqdif_custom_1.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqdif_custom_2.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqdif_id.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqdif_lg.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqdif_ph.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqdinfo.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqdsupport.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="pqptrarray.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="proc_bas.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="proc_not.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="proc_zlib.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="rec_base.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="rec_container.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="rec_datasource.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="rec_general.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="rec_observ.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="rec_settings.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="ser_alloc.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="ser_cont_el.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="ser_iter_el.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="str_base.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="str_chnk.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="str_flat.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="zconf.h">
<Filter>头文件</Filter>
</ClInclude>
<ClInclude Include="zlib.h">
<Filter>头文件</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<None Include="..\build-ubuntu.sh" />
<None Include="..\Makefile" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,79 @@
// Main include file for core WPT PQDIF classes.
// ---------------------------------------------
//
// File name: $Workfile: PQDIF_classes.h $
// Last modified: $Modtime: 10/11/01 11:24a $
// Last modified by: $Author: Tomm $
//
// VCS archive path: $Archive: /ElectrotekLibs/Borland/PQDIFlib/PQDIF_classes.h $
// VCS revision: $Revision: 17 $
// Windows stuff...
//#include <windows.h> WW 2024-05-19
// Array template from Standard Template Library (STL)
#include <vector>
#include <list>
#include <string>
#include <string.h>
#include <stdio.h>
#include <algorithm>
using namespace std;
// Math library support
#include <math.h>
//#include "pqdif_custom_1.h" // include implementation specific items WW 2024-05-19
// PQDIF headers
#include "pqdif_ph.h" // Physical definitions
#include "pqdif_lg.h" // Logical definitions
#include "pqdif_id.h" // Extensible ID definitions
// General purpose classes
#include "pqbytearray.h" // Byte array class - mostly compatible with MFC version
#include "pqptrarray.h" // Pointer array class - mostly compatible with MFC version
// Persistence controllers - Concrete uses an enum defined in pqdfacty.h
#include "pcn_base.h" // Interface (virtual base class)
// Stream classes
#include "str_base.h" // Interface (virtual base class)
#include "str_flat.h" // Flat file (for reading/writing temporary files)
#include "str_chnk.h" // Chunked streams
// Stream processor classes
#include "proc_bas.h" // Interface (virtual base class)
#include "proc_not.h" // Concrete: Nothing
#include "proc_zlib.h" // Concrete: ZLIB
// Record classes
#include "rec_base.h" // Record base class
#include "rec_general.h" // General record class (or "generic")
#include "rec_container.h" // Container record class - cast from general
#include "rec_datasource.h" // Data source record class - cast from general
#include "rec_observ.h" // Observation record class - cast from general
#include "rec_settings.h" // Settings record class - wrapper around general
// Element classes
#include "el_base.h" // Interface (virtual base class)
#include "el_coll.h" // Concrete: Collection
#include "el_scal.h" // Concrete: Scalar
#include "el_vect.h" // Concrete: Vector
// Serialization controller, iterator and allocator
#include "ser_cont_el.h"
#include "ser_iter_el.h"
#include "ser_alloc.h"
// Singleton objects
#include "pqdfacty.h" // Factory object for creating other PQDIF objects
#include "pqdinfo.h" // PQDIF information object (Singleton)
// Persistence controller - uses an enum defined in pqdfacty.h
#include "pcn_flat.h" // Concrete: Flat file controller
#include "pqdif_custom_2.h" // include implementation specific items

View File

@@ -0,0 +1,754 @@
/*
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"
static const char *global_ep;
const char *cJSON_GetErrorPtr(void) {return global_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 (d*0!=0) sprintf(str,"null"); /* This checks for NaN and Infinity */
else 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 **ep)
{
const char *ptr=str+1,*end_ptr=str+1;char *ptr2;char *out;int len=0;unsigned uc,uc2;
if (*str!='\"') {*ep=str;return 0;} /* not a string! */
while (*end_ptr!='\"' && *end_ptr && ++len) if (*end_ptr++ == '\\') end_ptr++; /* Skip escaped quotes. */
out=(char*)cJSON_malloc(len+1); /* This is how long we need for the string, roughly. */
if (!out) return 0;
item->valuestring=out; /* assign here so out will be deleted during cJSON_Delete() later */
item->type=cJSON_String;
ptr=str+1;ptr2=out;
while (ptr < end_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 (ptr >= end_ptr) {*ep=str;return 0;} /* invalid */
if ((uc>=0xDC00 && uc<=0xDFFF) || uc==0) {*ep=str;return 0;} /* check for invalid. */
if (uc>=0xD800 && uc<=0xDBFF) /* UTF16 surrogate pairs. */
{
if (ptr+6 > end_ptr) {*ep=str;return 0;} /* invalid */
if (ptr[1]!='\\' || ptr[2]!='u') {*ep=str;return 0;} /* missing second-half of surrogate. */
uc2=parse_hex4(ptr+3);ptr+=6;
if (uc2<0xDC00 || uc2>0xDFFF) {*ep=str;return 0;} /* 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++;
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;
if (!str)
{
if (p) out=ensure(p,3);
else out=(char*)cJSON_malloc(3);
if (!out) return 0;
strcpy(out,"\"\"");
return out;
}
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;
}
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,const char **ep);
static char *print_value(cJSON *item,int depth,int fmt,printbuffer *p);
static const char *parse_array(cJSON *item,const char *value,const char **ep);
static char *print_array(cJSON *item,int depth,int fmt,printbuffer *p);
static const char *parse_object(cJSON *item,const char *value,const char **ep);
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,**ep=return_parse_end?return_parse_end:&global_ep;
cJSON *c=cJSON_New_Item();
*ep=0;
if (!c) return 0; /* memory fail */
end=parse_value(c,skip(value),ep);
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);
}
/* Parser core - when encountering text, process appropriately. */
static const char *parse_value(cJSON *item,const char *value,const char **ep)
{
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,ep); }
if (*value=='-' || (*value>='0' && *value<='9')) { return parse_number(item,value); }
if (*value=='[') { return parse_array(item,value,ep); }
if (*value=='{') { return parse_object(item,value,ep); }
*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,const char **ep)
{
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),ep)); /* 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),ep));
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,const char **ep)
{
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),ep));
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),ep)); /* 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),ep));
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),ep)); /* 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;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 && !fail)
{
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?array->child:0;while (c && item>0) item--,c=c->next; return c;}
cJSON *cJSON_GetObjectItem(cJSON *object,const char *string) {cJSON *c=object?object->child:0;while (c && cJSON_strcasecmp(c->string,string)) c=c->next; return c;}
int cJSON_HasObjectItem(cJSON *object,const char *string) {return cJSON_GetObjectItem(object,string)?1:0;}
/* 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);if(!item->valuestring){cJSON_Delete(item);return 0;}}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(!n){cJSON_Delete(a);return 0;}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(!n){cJSON_Delete(a);return 0;}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(!n){cJSON_Delete(a);return 0;}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(!n){cJSON_Delete(a);return 0;}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. */
}

View File

@@ -0,0 +1,153 @@
/*
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 (1 << 0)
#define cJSON_True (1 << 1)
#define cJSON_NULL (1 << 2)
#define cJSON_Number (1 << 3)
#define cJSON_String (1 << 4)
#define cJSON_Array (1 << 5)
#define cJSON_Object (1 << 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);
extern int cJSON_HasObjectItem(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. */
/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error. If not, then cJSON_GetErrorPtr() does the job. */
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))
/* Macro for iterating over an array */
#define cJSON_ArrayForEach(pos, head) for(pos = (head)->child; pos != NULL; pos = pos->next)
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -0,0 +1,564 @@
/*
** CPQDIF_Element class. The base class for PQDIF elements.
** --------------------------------------------------------------------------
**
** File name: $Workfile: el_base.cpp $
** Last modified: $Modtime: 11/13/00 3:40p $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/el_base.cpp $
** VCS revision: $Revision: 13 $
*/
#include "PQDIF_classes.h"
CPQDIF_Element::CPQDIF_Element()
{
m_pRecord = NULL;
memset( &m_tag, 0, sizeof( m_tag ) );
m_typePhysical = 0;
}
#ifdef PQDIF_USE_COM
bool CPQDIF_Element::convertFromVariant( const VARIANT & value, PQDIFValue& m_value ) const
{
bool status = true;
INT1 val_int1;
INT2 val_int2;
INT4 val_int4;
// First, verify the variant physical type matches
// (and pull out the integer values)
status = TRUE;
switch( m_typePhysical )
{
case ID_PHYS_TYPE_BOOLEAN1 :
case ID_PHYS_TYPE_BOOLEAN2 :
case ID_PHYS_TYPE_BOOLEAN4 :
if( value.vt != VT_BOOL )
status = false;
break;
case ID_PHYS_TYPE_CHAR1 :
case ID_PHYS_TYPE_INTEGER1 :
case ID_PHYS_TYPE_UNS_INTEGER1 :
switch( value.vt )
{
case VT_UI1:
val_int1 = (INT1) value.bVal;
break;
case VT_I1:
val_int1 = (INT1) value.cVal;
break;
default:
status = false;
}
break;
case ID_PHYS_TYPE_CHAR2 :
case ID_PHYS_TYPE_INTEGER2 :
case ID_PHYS_TYPE_UNS_INTEGER2 :
switch( value.vt )
{
case VT_UI2:
val_int2 = (INT2) value.uiVal;
break;
case VT_I2:
val_int2 = (INT2) value.iVal;
break;
default:
status = false;
}
break;
case ID_PHYS_TYPE_INTEGER4 :
case ID_PHYS_TYPE_UNS_INTEGER4 :
switch( value.vt )
{
case VT_UI4:
val_int4 = (INT4) value.ulVal;
break;
case VT_I4:
val_int4 = (INT4) value.lVal;
break;
default:
status = false;
}
break;
// Real/complex
case ID_PHYS_TYPE_REAL4 :
if( value.vt != VT_R4 )
status = false;
break;
case ID_PHYS_TYPE_REAL8 :
if( value.vt != VT_R4 )
status = false;
break;
case ID_PHYS_TYPE_COMPLEX8 :
case ID_PHYS_TYPE_COMPLEX16 :
//if( value.vt == VT_ARRAY ) ???
break;
case ID_PHYS_TYPE_TIMESTAMPPQDIF :
if( value.vt != VT_DATE )
status = false;
break;
case ID_PHYS_TYPE_GUID :
//if( value.vt == VT_ARRAY ) ???
break;
default:
status = false;
break;
}
if( status )
{
switch( m_typePhysical )
{
case ID_PHYS_TYPE_BOOLEAN1 :
m_value.bool1 = (BOOL1) value.boolVal;
case ID_PHYS_TYPE_BOOLEAN2 :
m_value.bool2 = (BOOL2) value.boolVal;
case ID_PHYS_TYPE_BOOLEAN4 :
m_value.bool4 = (BOOL4) value.boolVal;
break;
case ID_PHYS_TYPE_CHAR1 :
m_value.char1 = (CHAR1) val_int1;
break;
case ID_PHYS_TYPE_INTEGER1 :
m_value.int1 = (INT1) val_int1;
break;
case ID_PHYS_TYPE_UNS_INTEGER1 :
m_value.uint1 = (UINT1) val_int1;
break;
case ID_PHYS_TYPE_CHAR2 :
m_value.char2 = (CHAR2) val_int2;
break;
case ID_PHYS_TYPE_INTEGER2 :
m_value.int2 = (INT2) val_int2;
break;
case ID_PHYS_TYPE_UNS_INTEGER2 :
m_value.uint2 = (UINT2) val_int2;
break;
case ID_PHYS_TYPE_INTEGER4 :
m_value.int4 = (INT4) val_int4;
break;
case ID_PHYS_TYPE_UNS_INTEGER4 :
m_value.uint4 = (UINT4) val_int4;
break;
// Real/complex
case ID_PHYS_TYPE_REAL4 :
m_value.real4 = (REAL4) value.fltVal;
break;
case ID_PHYS_TYPE_REAL8 :
m_value.real8 = (REAL8) value.dblVal;
break;
case ID_PHYS_TYPE_COMPLEX8 :
case ID_PHYS_TYPE_COMPLEX16 :
// need to fix
// SAFEARRAY?
break;
// Date/time
case ID_PHYS_TYPE_TIMESTAMPPQDIF :
// From the documentation, it appears that the
// whole number portion of the DATE is compatible
// with our .day member. (Although it is possible that
// they will be off by 1 day...)
m_value.ts.day = (UINT4) ( value.date );
// Convert the fractional day to fractional seconds.
m_value.ts.sec = (REAL8) ( value.date - (DATE) m_value.ts.day );
m_value.ts.sec *= (REAL8) SECONDS_PER_DAY;
break;
// GUID
case ID_PHYS_TYPE_GUID :
// need to fix
// SAFEARRAY?
break;
default:
status = false;
break;
}
}
return status;
}
bool CPQDIF_Element::convertToVariant( const PQDIFValue& m_value, VARIANT & value ) const
{
bool status = true;
string strRep;
VariantInit( &value );
USES_CONVERSION;
if( status )
{
switch( m_typePhysical )
{
case ID_PHYS_TYPE_BOOLEAN1 :
value.vt = VT_BOOL;
value.boolVal = m_value.bool1;
break;
case ID_PHYS_TYPE_CHAR1 :
value.vt = VT_I1;
value.cVal = m_value.char1;
break;
case ID_PHYS_TYPE_INTEGER1 :
value.vt = VT_I1;
value.cVal = m_value.int1;
break;
case ID_PHYS_TYPE_UNS_INTEGER1 :
// VT_UI1 / value.bVal
value.vt = VT_I1;
value.cVal = m_value.uint1;
break;
case ID_PHYS_TYPE_BOOLEAN2 :
value.vt = VT_BOOL;
value.boolVal = m_value.bool2;
break;
case ID_PHYS_TYPE_CHAR2 :
// Single-char Unicode string instead?
value.vt = VT_I2;
value.iVal = m_value.char2;
break;
case ID_PHYS_TYPE_INTEGER2 :
value.vt = VT_I2;
value.iVal = m_value.int2;
break;
case ID_PHYS_TYPE_UNS_INTEGER2 :
//VT_UI2 / uiVal
value.vt = VT_I2;
value.iVal = m_value.uint2 ;
break;
case ID_PHYS_TYPE_BOOLEAN4 :
value.vt = VT_BOOL;
value.boolVal = (VARIANT_BOOL) m_value.bool4;
break;
case ID_PHYS_TYPE_INTEGER4 :
value.vt = VT_I4;
value.lVal = m_value.int4;
break;
case ID_PHYS_TYPE_UNS_INTEGER4 :
// VT_UI4 / ulVal
value.vt = VT_I4;
value.lVal = m_value.uint4;
break;
// Real/complex
case ID_PHYS_TYPE_REAL4 :
value.vt = VT_R4;
value.fltVal = m_value.real4;
break;
case ID_PHYS_TYPE_REAL8 :
value.vt = VT_R8;
value.dblVal = m_value.real8;
break;
case ID_PHYS_TYPE_COMPLEX8 :
case ID_PHYS_TYPE_COMPLEX16 :
// need to fix
// SAFEARRAY?
//value.vt = VT_ARRAY;
//value.parray = NULL;
// In string form ("real imag")
// strRep = _T( "" );
strRep = "";
char szBuffer[64];
if( m_typePhysical == ID_PHYS_TYPE_COMPLEX8 )
{
sprintf( szBuffer, "%.8g %.8g",
m_value.complex8.real,
m_value.complex8.image );
strRep = szBuffer;
}
else
{
sprintf( szBuffer, "%.16g %.16g",
m_value.complex16.real,
m_value.complex16.image );
strRep = szBuffer;
}
value.vt = VT_BSTR;
#if _MSC_VER >= 1100
value.bstrVal = SysAllocString(_bstr_t(strRep.c_str()));
#else
value.bstrVal = SysAllocString(A2W(strRep.c_str()));
#endif
break;
// Date/time
case ID_PHYS_TYPE_TIMESTAMPPQDIF :
value.vt = VT_DATE;
value.date = (double) m_value.ts.day
+ ( (double) m_value.ts.sec / (double) SECONDS_PER_DAY );
break;
// GUID
case ID_PHYS_TYPE_GUID :
status = theSupport.NewVariantArrayFromGUID( value, m_value.guid );
// need to fix
// SAFEARRAY?
//value.vt = VT_ARRAY;
//value.parray = NULL;
//unsigned char ** pstrRPC;
// Generate a GUID string
//UuidToString( &m_value.guid, pstrRPC );
//RpcStringFree( pstrRPC );
// String in this format:
// {89738618-F1C3-11cf-9D89-0080C72E70A3}
//{
//char * pstr = strRep.GetBuffer( 64 );
//sprintf( pstr, "{%08.8lx-%04.4x-%04.4x-%02.2x%02.2x%02.2x%02.2x}",
// m_value.guid.Data1,
// m_value.guid.Data2,
// m_value.guid.Data3,
// (short) m_value.guid.Data4[ 0 ],
// (short) m_value.guid.Data4[ 1 ],
// (short) m_value.guid.Data4[ 2 ],
// (short) m_value.guid.Data4[ 3 ]
// );
//strRep.ReleaseBuffer();
//}
// Return it back in the variant...
//value.vt = VT_BSTR | VT_BYREF;
//*value.pbstrVal = strRep.AllocSysString();
//value.vt = VT_BSTR;
//value.bstrVal = strRep.AllocSysString();
break;
default:
status = false;
break;
}
}
return status;
}
#endif
bool CPQDIF_Element::convertFromDouble( double valueSource, PQDIFValue& valueTarget ) const
{
bool status = true;
// First, verify the variant physical type matches
// (and pull out the integer values)
if( status )
{
switch( m_typePhysical )
{
case ID_PHYS_TYPE_BOOLEAN1 :
valueTarget.bool1 = (BOOL1) valueSource;
break;
case ID_PHYS_TYPE_BOOLEAN2 :
valueTarget.bool2 = (BOOL2) valueSource;
break;
case ID_PHYS_TYPE_BOOLEAN4 :
valueTarget.bool4 = (BOOL4) valueSource;
break;
case ID_PHYS_TYPE_CHAR1 :
valueTarget.char1 = (CHAR1) valueSource;
break;
case ID_PHYS_TYPE_INTEGER1 :
valueTarget.int1 = (INT1) valueSource;
break;
case ID_PHYS_TYPE_UNS_INTEGER1 :
valueTarget.uint1 = (UINT1) valueSource;
break;
case ID_PHYS_TYPE_CHAR2 :
valueTarget.char2 = (CHAR2) valueSource;
break;
case ID_PHYS_TYPE_INTEGER2 :
valueTarget.int2 = (INT2) valueSource;
break;
case ID_PHYS_TYPE_UNS_INTEGER2 :
valueTarget.uint2 = (UINT2) valueSource;
break;
case ID_PHYS_TYPE_INTEGER4 :
valueTarget.int4 = (INT4) valueSource;
break;
case ID_PHYS_TYPE_UNS_INTEGER4 :
valueTarget.uint4 = (UINT4) valueSource;
break;
// Real/complex
case ID_PHYS_TYPE_REAL4 :
valueTarget.real4 = (REAL4) valueSource;
break;
case ID_PHYS_TYPE_REAL8 :
valueTarget.real8 = (REAL8) valueSource;
break;
case ID_PHYS_TYPE_COMPLEX8 :
valueTarget.complex8.real = (REAL4) valueSource;
valueTarget.complex8.image = 0.0;
break;
case ID_PHYS_TYPE_COMPLEX16 :
valueTarget.complex16.real = (REAL4) valueSource;
valueTarget.complex16.image = 0.0;
break;
// Date/time
case ID_PHYS_TYPE_TIMESTAMPPQDIF :
// From the documentation, it appears that the
// whole number portion of the DATE is compatible
// with our .day member. (Although it is possible that
// they will be off by 1 day...)
valueTarget.ts.day = (UINT4) ( valueSource );
// Convert the fractional day to fractional seconds.
valueTarget.ts.sec = (REAL8) ( valueSource - (double) valueTarget.ts.day );
valueTarget.ts.sec *= (REAL8) SECONDS_PER_DAY;
break;
// GUID
case ID_PHYS_TYPE_GUID :
// Cannot convert from double.
break;
default:
status = false;
break;
}
}
return status;
}
bool CPQDIF_Element::convertToDouble( const PQDIFValue& valueSource, double& valueTarget ) const
{
bool status = true;
valueTarget = 0.0;
if( status )
{
switch( m_typePhysical )
{
case ID_PHYS_TYPE_BOOLEAN1 :
valueTarget = (double) valueSource.bool1;
break;
case ID_PHYS_TYPE_CHAR1 :
valueTarget = (double) valueSource.char1;
break;
case ID_PHYS_TYPE_INTEGER1 :
valueTarget = (double) valueSource.int1;
break;
case ID_PHYS_TYPE_UNS_INTEGER1 :
valueTarget = (double) valueSource.uint1;
break;
case ID_PHYS_TYPE_BOOLEAN2 :
valueTarget = (double) valueSource.bool2;
break;
case ID_PHYS_TYPE_CHAR2 :
// Single-char Unicode string instead?
valueTarget = (double) valueSource.char2;
break;
case ID_PHYS_TYPE_INTEGER2 :
valueTarget = (double) valueSource.int2;
break;
case ID_PHYS_TYPE_UNS_INTEGER2 :
valueTarget = (double) valueSource.uint2 ;
break;
case ID_PHYS_TYPE_BOOLEAN4 :
valueTarget = (double) valueSource.bool4;
break;
case ID_PHYS_TYPE_INTEGER4 :
valueTarget = (double) valueSource.int4;
break;
case ID_PHYS_TYPE_UNS_INTEGER4 :
valueTarget = (double) valueSource.uint4;
break;
// Real/complex
case ID_PHYS_TYPE_REAL4 :
valueTarget = (double) valueSource.real4;
break;
case ID_PHYS_TYPE_REAL8 :
valueTarget = (double) valueSource.real8;
break;
case ID_PHYS_TYPE_COMPLEX8 :
case ID_PHYS_TYPE_COMPLEX16 :
// Cannot convert to double.
break;
// Date/time
case ID_PHYS_TYPE_TIMESTAMPPQDIF :
//valueTarget.vt = VT_DATE;
valueTarget = (double) valueSource.ts.day
+ ( (double) valueSource.ts.sec / (double) SECONDS_PER_DAY );
break;
// GUID
case ID_PHYS_TYPE_GUID :
// Cannot convert to double.
break;
default:
status = false;
break;
}
}
return status;
}
long CPQDIF_Element::getNumBytesOfType( void ) const
{
return theInfo.GetNumBytesOfType( m_typePhysical );
}

View File

@@ -0,0 +1,102 @@
/*
** class CPQDIF_Element
** --------------------------------------------------------------------------
**
** File name: $Workfile: el_base.h $
** Last modified: $Modtime: 12/01/00 8:34a $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/el_base.h $
** VCS revision: $Revision: 11 $
*/
union PQDIFValue
{
BOOL1 bool1;
BOOL2 bool2;
BOOL4 bool4;
CHAR1 char1; // ASCII string character
CHAR2 char2; // Unicode string character
INT1 int1;
INT2 int2;
INT4 int4;
UINT1 uint1;
UINT2 uint2;
UINT4 uint4;
REAL4 real4;
REAL8 real8;
COMPLEX8 complex8;
COMPLEX16 complex16;
TIMESTAMPPQDIF ts;
GUID guid;
};
class CPQDIF_Element
{
// Construct/destruct
public:
CPQDIF_Element();
virtual ~CPQDIF_Element() {}
// Operator(s)
public:
// Attributes
public:
virtual long GetElementType( void ) const
{return -1; }
inline CPQDIFRecord * GetRecord( void )
{
return m_pRecord;
}
virtual void SetRecord( CPQDIFRecord * pRecord )
{
m_pRecord = pRecord;
}
// Operations
public:
inline const GUID& GetTag( void ) const
{ return m_tag; }
inline void SetTag( const GUID& tag )
{
m_tag = tag;
if( m_pRecord )
m_pRecord->SetChanged( true );
}
inline long GetPhysicalType( void ) const
{ return m_typePhysical; }
virtual void SetPhysicalType( long type )
{
m_typePhysical = type;
if( m_pRecord )
m_pRecord->SetChanged( true );
}
// Implementation
protected:
#ifdef PQDIF_USE_COM // if COM support, then VARIANT is available
bool convertToVariant( const PQDIFValue& valuePQDIF, VARIANT & valueVariant ) const;
bool convertFromVariant( const VARIANT & valueVariant, PQDIFValue& valuePQDIF ) const;
#endif
bool convertToDouble( const PQDIFValue& m_value, double& value ) const;
bool convertFromDouble( double value, PQDIFValue& m_value ) const;
long getNumBytesOfType( void ) const;
inline BYTE * getPointerToValue( PQDIFValue& value ) const { return (BYTE *)&value; }
inline const BYTE * getPointerToValue( const PQDIFValue& value ) const { return (const BYTE *)&value; }
// Member data
protected:
GUID m_tag; // Tag for this element.
long m_typePhysical; // Physical type for this element.
CPQDIFRecord * m_pRecord; // The record that this element
// is associated with.
};

View File

@@ -0,0 +1,419 @@
/*
** CPQDIF_E_Collection class. Implements the PQDIF collection element.
** --------------------------------------------------------------------------
**
** File name: $Workfile: el_coll.cpp $
** Last modified: $Modtime: 11/21/00 10:59a $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/el_coll.cpp $
** VCS revision: $Revision: 17 $
*/
#include "PQDIF_classes.h"
// Local constants
const char cTerminator = '\0';
// Relational operators for for ordering a collection.
bool operator<( const CPQDIF_Element * pel, const GUID &tag )
{
return ( memcmp( &(pel->GetTag()), &tag, sizeof( tag ) ) < 0 );
}
bool operator<( const GUID &tag, const CPQDIF_Element * pel )
{
return ( memcmp( &tag, &(pel->GetTag()), sizeof( tag ) ) < 0 );
}
// Construction
// ============
CPQDIF_E_Collection::CPQDIF_E_Collection()
{
m_array.reserve( 32 );
}
CPQDIF_E_Collection::~CPQDIF_E_Collection()
{
// Destroy all elements in the array
CArrayElements::iterator iter;
for( iter = m_array.begin(); iter != m_array.end(); iter++ )
{
delete *iter;
*iter = NULL;
}
}
long CPQDIF_E_Collection::GetCount( void ) const
{
return m_array.size();
}
CPQDIF_Element * CPQDIF_E_Collection::GetElement( long index ) const
{
CPQDIF_Element * pel = NULL;
if( index >= 0 && index < GetCount() )
{
pel = m_array[ index ];
}
return pel;
}
CPQDIF_Element * CPQDIF_E_Collection::GetElement( const GUID& tag, long elementType ) const
{
CPQDIF_Element * pelReturn = NULL;
// See if specified element is in the collection.
CArrayElements::const_iterator iter;
iter = lower_bound( m_array.begin(), m_array.end(), tag );
while( pelReturn == NULL
&& iter != m_array.end()
&& *iter != NULL
&& PQDIF_IsEqualGUID( (*iter)->GetTag(), tag ) )
{
// Matching type.
if( elementType == -1
|| elementType == (*iter)->GetElementType() )
{
pelReturn = *iter;
}
iter++;
}
return pelReturn;
}
void CPQDIF_E_Collection::SetRecord( CPQDIFRecord * pRecord )
{
CPQDIF_Element * pel;
// Call the base class method.
CPQDIF_Element::SetRecord( pRecord );
// Do the same thing to the objects we own
CArrayElements::iterator iter;
for( iter = m_array.begin(); iter != m_array.end(); iter++ )
{
pel = *iter;
//ASSERT_VALID( pel );
if( pel )
{
pel->SetRecord( pRecord );
}
}
return;
}
void CPQDIF_E_Collection::Add( CPQDIF_Element * pel )
{
// Add the element to the collection.
CArrayElements::iterator iter = upper_bound( m_array.begin(), m_array.end(), pel->GetTag() );
m_array.insert( iter, pel );
// Set the element to reference the collections record.
if( pel )
pel->SetRecord( GetRecord() );
// Signal that the record has changed.
if( m_pRecord )
m_pRecord->SetChanged( true );
}
// Should this delete the element or not?
void CPQDIF_E_Collection::RemoveAt( long index )
{
// If a valid element was specified then ....
//ASSERT( index >= 0 && index < GetCount() );
if( index >= 0 && index < GetCount() )
{
// Dereference the element.
CArrayElements::iterator where = m_array.begin();
where += index;
CPQDIF_Element * pel = *where;
// Clear the element's reference to the record.
if( pel )
pel->SetRecord( NULL );
// Remove it from the list.
m_array.erase( where );
// Mark the collection as dirty.
if( m_pRecord )
m_pRecord->SetChanged( true );
}
}
void CPQDIF_E_Collection::AddOrReplace( CPQDIF_Element * pel )
{
bool bFound = false;
CPQDIF_Element * pelToCompare = NULL;
const GUID & tagToAdd = pel->GetTag();
// See if this tag already exists
CArrayElements::iterator iter;
iter = lower_bound( m_array.begin(), m_array.end(), tagToAdd );
if( iter != m_array.end() )
{
pelToCompare = *iter;
if( pelToCompare )
{
// Matching tags?
if( PQDIF_IsEqualGUID( pelToCompare->GetTag(), tagToAdd ) )
{
// Delete the old element.
delete pelToCompare;
// Add the new element to the collection.
*iter = pel;
// Signal that the element is found.
bFound = true;
}
}
}
// If an existing element was not found then add the element.
if( !bFound )
{
m_array.insert( iter, pel );
}
// Set the element to reference the collections record.
if( pel )
pel->SetRecord( GetRecord() );
// Signal that the record has changed.
if( m_pRecord )
m_pRecord->SetChanged( true );
}
void CPQDIF_E_Collection::SetVectorString
(
const GUID& tagElement,
const char * text,
bool allowReplace
)
{
CPQDIF_E_Vector * pvectString;
if( text )
{
// Create the new vector to hold the string
pvectString = (CPQDIF_E_Vector *) theFactory.NewElement( ID_ELEMENT_TYPE_VECTOR );
if( pvectString )
{
// Set it up ...
pvectString->SetTag( tagElement );
pvectString->SetPhysicalType( ID_PHYS_TYPE_CHAR1 );
pvectString->SetValues( text );
// Add it
if( allowReplace )
AddOrReplace( pvectString );
else
Add( pvectString );
}
}
}
// Parameterized SetVector...() functions
// ======================================
#define SETVECTOR( nametype, type, idtype ) \
void CPQDIF_E_Collection::SetVector##nametype \
( const GUID& tagElement, \
const type * values, \
long count, \
bool allowReplace ) \
{ \
CPQDIF_E_Vector * pvect; \
if( values ) \
{ \
/* Create the new vector to hold the string */ \
pvect = (CPQDIF_E_Vector *) theFactory.NewElement( ID_ELEMENT_TYPE_VECTOR ); \
if( pvect ) \
{ \
/* Set it up ... */ \
pvect->SetTag( tagElement ); \
pvect->SetPhysicalType( idtype ); \
pvect->SetValues##nametype( values, count ); \
/* Add it */ \
if( allowReplace ) \
AddOrReplace( pvect ); \
else \
Add( pvect ); \
} \
} \
}
SETVECTOR( INT1, INT1, ID_PHYS_TYPE_INTEGER1 );
SETVECTOR( INT2, INT2, ID_PHYS_TYPE_INTEGER2 );
SETVECTOR( INT4, INT4, ID_PHYS_TYPE_INTEGER4 );
SETVECTOR( UINT4, UINT4, ID_PHYS_TYPE_UNS_INTEGER4 );
SETVECTOR( REAL4, REAL4, ID_PHYS_TYPE_REAL4 );
SETVECTOR( REAL8, REAL8, ID_PHYS_TYPE_REAL8 );
SETVECTOR( TimeStamp, TIMESTAMPPQDIF, ID_PHYS_TYPE_TIMESTAMPPQDIF );
bool CPQDIF_E_Collection::GetVectorString
(
const GUID& tagElement,
char * text,
long max
) const
{
bool status = false;
const CPQDIF_Element * pel;
string values;
pel = GetElement( tagElement );
if( pel && pel->GetElementType() == ID_ELEMENT_TYPE_VECTOR )
{
const CPQDIF_E_Vector * pvect = (const CPQDIF_E_Vector *) pel;
status = pvect->GetValues( values );
if( status )
{
#ifdef WIN32
strncpy_s(text, strlen(text),values.c_str(), max);
#else
strncpy(text, values.c_str(), max);
#endif // WIN32
text[ max - 1 ] = cTerminator;
}
}
return status;
}
// Parameterized GetVector...() functions
// ======================================
#define GETVECTOR( nametype, type ) \
long CPQDIF_E_Collection::GetVector##nametype \
( \
const GUID& tagElement, \
type * values, \
long max \
) const \
{ \
long sizeActual = 0; \
const CPQDIF_Element * pel; \
pel = GetElement( tagElement ); \
if( pel && pel->GetElementType() == ID_ELEMENT_TYPE_VECTOR ) \
{ \
const CPQDIF_E_Vector * pvect = (const CPQDIF_E_Vector *) pel; \
sizeActual = pvect->GetValues##nametype( values, max ); \
} \
return sizeActual; \
}
GETVECTOR( INT1, INT1 );
GETVECTOR( INT2, INT2 );
GETVECTOR( INT4, INT4 );
GETVECTOR( UINT4, UINT4 );
GETVECTOR( REAL4, REAL4 );
GETVECTOR( REAL8, REAL8 );
GETVECTOR( TimeStamp, TIMESTAMPPQDIF );
// Parameterized SetScalar...() functions
// ======================================
#define SETSCALAR( nametype, type ) \
void CPQDIF_E_Collection::SetScalar##nametype \
( \
const GUID& tagElement, \
type value, \
bool allowReplace \
) \
{ \
CPQDIF_E_Scalar * psc; \
psc = (CPQDIF_E_Scalar *) theFactory.NewElement( ID_ELEMENT_TYPE_SCALAR ); \
if( psc ) \
{ \
psc->SetTag( tagElement ); \
psc->SetValue##nametype( value ); \
if( allowReplace ) \
AddOrReplace( psc ); \
else \
Add( psc ); \
} \
}
SETSCALAR( BOOL4, bool )
SETSCALAR( INT2, INT2 )
SETSCALAR( UINT2, UINT2 )
SETSCALAR( INT4, INT4 )
SETSCALAR( UINT4, UINT4 )
SETSCALAR( REAL4, REAL4 )
SETSCALAR( REAL8, REAL8 )
SETSCALAR( COMPLEX8, COMPLEX8 )
SETSCALAR( COMPLEX16, COMPLEX16 )
SETSCALAR( GUID, GUID )
SETSCALAR( TimeStamp, TIMESTAMPPQDIF )
// Parameterized GetScalar...() functions
// ======================================
#define GETSCALAR( nametype, type ) \
bool CPQDIF_E_Collection::GetScalar##nametype \
( \
const GUID& tagElement, \
type& value \
) const \
{ \
bool status = false; \
const CPQDIF_Element * pel; \
pel = GetElement( tagElement ); \
if( pel && pel->GetElementType() == ID_ELEMENT_TYPE_SCALAR ) \
{ \
const CPQDIF_E_Scalar * psc = (const CPQDIF_E_Scalar *) pel; \
status = psc->GetValue##nametype( value ); \
} \
return status; \
}
GETSCALAR( BOOL4, bool )
GETSCALAR( INT2, INT2 )
GETSCALAR( UINT2, UINT2 )
GETSCALAR( INT4, INT4 )
GETSCALAR( UINT4, UINT4 )
GETSCALAR( REAL4, REAL4 )
GETSCALAR( REAL8, REAL8 )
GETSCALAR( COMPLEX8, COMPLEX8 )
GETSCALAR( COMPLEX16, COMPLEX16 )
GETSCALAR( GUID, GUID )
GETSCALAR( TimeStamp, TIMESTAMPPQDIF )

View File

@@ -0,0 +1,279 @@
// File name: $Workfile: el_coll.h $
// Last modified: $Modtime: 11/20/00 2:27p $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/el_coll.h $
// VCS revision: $Revision: 13 $
//typedef list<CClassInfo> CClassInfoList;
typedef CPQDIF_Element * PElement;
typedef vector<PElement> CArrayElements;
class CPQDIF_E_Collection : public CPQDIF_Element
{
public:
CPQDIF_E_Collection();
virtual ~CPQDIF_E_Collection();
// Operator(s)
public:
// Attributes
public:
virtual long GetElementType( void ) const
{ return ID_ELEMENT_TYPE_COLLECTION; }
virtual void SetRecord( CPQDIFRecord * pRecord );
// Operations
public:
// Read
long GetCount( void ) const;
CPQDIF_Element * GetElement( long index ) const;
CPQDIF_Element * GetElement( const GUID& tag, long elementType = -1 ) const;
// Modify
void Add( CPQDIF_Element * pel );
void RemoveAt( long index );
void AddOrReplace( CPQDIF_Element * pel );
// Set vectors
void SetVectorString
(
const GUID& tagElement,
const char * text,
bool allowReplace = true
);
void SetVectorINT1
(
const GUID& tagElement,
const INT1 * values,
long count,
bool allowReplace = true
);
void SetVectorINT2
(
const GUID& tagElement,
const INT2 * values,
long count,
bool allowReplace = true
);
void SetVectorINT4
(
const GUID& tagElement,
const INT4 * values,
long count,
bool allowReplace = true
);
void SetVectorUINT4
(
const GUID& tagElement,
const UINT4 * values,
long count,
bool allowReplace = true
);
void SetVectorREAL4
(
const GUID& tagElement,
const REAL4 * values,
long count,
bool allowReplace = true
);
void SetVectorREAL8
(
const GUID& tagElement,
const REAL8 * values,
long count,
bool allowReplace = true
);
void SetVectorTimeStamp
(
const GUID& tagElement,
const TIMESTAMPPQDIF * values,
long count,
bool allowReplace = true
);
// Get vectors
bool GetVectorString
(
const GUID& tagElement,
char * text,
long max
) const;
long GetVectorINT1
(
const GUID& tagElement,
INT1 * values,
long max
) const;
long GetVectorINT2
(
const GUID& tagElement,
INT2 * values,
long max
) const;
long GetVectorINT4
(
const GUID& tagElement,
INT4 * values,
long max
) const;
long GetVectorUINT4
(
const GUID& tagElement,
UINT4 * values,
long max
) const;
long GetVectorREAL4
(
const GUID& tagElement,
REAL4 * values,
long max
) const;
long GetVectorREAL8
(
const GUID& tagElement,
REAL8 * values,
long max
) const;
long GetVectorTimeStamp
(
const GUID& tagElement,
TIMESTAMPPQDIF * values,
long max
) const;
// Set scalars
void SetScalarGUID
(
const GUID& tagElement,
GUID value,
bool allowReplace = true
);
void SetScalarTimeStamp
(
const GUID& tagElement,
TIMESTAMPPQDIF value,
bool allowReplace = true
);
void SetScalarUINT2
(
const GUID& tagElement,
UINT2 value,
bool allowReplace = true
);
void SetScalarINT2
(
const GUID& tagElement,
INT2 value,
bool allowReplace = true
);
void SetScalarUINT4
(
const GUID& tagElement,
UINT4 value,
bool allowReplace = true
);
void SetScalarINT4
(
const GUID& tagElement,
INT4 value,
bool allowReplace = true
);
void SetScalarBOOL4
(
const GUID& tagElement,
bool value,
bool allowReplace = true
);
void SetScalarREAL4
(
const GUID& tagElement,
REAL4 value,
bool allowReplace = true
);
void SetScalarREAL8
(
const GUID& tagElement,
REAL8 value,
bool allowReplace = true
);
void SetScalarCOMPLEX8
(
const GUID& tagElement,
COMPLEX8 value,
bool allowReplace = true
);
void SetScalarCOMPLEX16
(
const GUID& tagElement,
COMPLEX16 value,
bool allowReplace = true
);
// Get scalars
bool GetScalarGUID
(
const GUID& tagElement,
GUID& value
) const;
bool GetScalarTimeStamp
(
const GUID& tagElement,
TIMESTAMPPQDIF& value
) const;
bool GetScalarUINT2
(
const GUID& tagElement,
UINT2& value
) const;
bool GetScalarINT2
(
const GUID& tagElement,
INT2& value
) const;
bool GetScalarUINT4
(
const GUID& tagElement,
UINT4& value
) const;
bool GetScalarINT4
(
const GUID& tagElement,
INT4& value
) const;
bool GetScalarBOOL4
(
const GUID& tagElement,
bool& value
) const;
bool GetScalarREAL4
(
const GUID& tagElement,
REAL4& value
) const;
bool GetScalarREAL8
(
const GUID& tagElement,
REAL8& value
) const;
bool GetScalarCOMPLEX8
(
const GUID& tagElement,
COMPLEX8& value
) const;
bool GetScalarCOMPLEX16
(
const GUID& tagElement,
COMPLEX16& value
) const;
// Implementation
private:
// Member data
private:
CArrayElements m_array;
};

View File

@@ -0,0 +1,367 @@
/*
** CPQDIF_E_Scalar class. Implements the PQDIF scalar element.
** --------------------------------------------------------------------------
**
** File name: $Workfile: el_scal.cpp $
** Last modified: $Modtime: 12/22/00 10:30a $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/el_scal.cpp $
** VCS revision: $Revision: 12 $
*/
#include "PQDIF_classes.h"
// Construction
// ============
CPQDIF_E_Scalar::CPQDIF_E_Scalar()
{
memset( &m_value, 0, sizeof( m_value ) );
}
CPQDIF_E_Scalar::~CPQDIF_E_Scalar()
{
}
#ifdef PQDIF_USE_COM
bool CPQDIF_E_Scalar::SetValue( long typePhysical, VARIANT & value )
{
bool status = false;
m_typePhysical = typePhysical;
if( m_pRecord )
m_pRecord->SetChanged( true );
status = convertFromVariant( value, m_value );
return status;
}
bool CPQDIF_E_Scalar::GetValue( VARIANT& value )
{
bool status = true;
status = convertToVariant( m_value, value );
return status;
}
#endif
bool CPQDIF_E_Scalar::SetValue( long typePhysical, PQDIFValue& value )
{
bool status = false;
int iSize = theInfo.GetNumBytesOfType( typePhysical );
if( iSize > 0 )
{
m_typePhysical = typePhysical;
memcpy( (void *)&m_value, (void *)&value, iSize );
status = true;
if( m_pRecord )
m_pRecord->SetChanged( true );
}
return status;
}
bool CPQDIF_E_Scalar::GetValue( long& typePhysical, PQDIFValue& value ) const
{
bool status = false;
if( m_typePhysical != 0 )
{
typePhysical = m_typePhysical;
value = m_value;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueUINT2( UINT2 value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_UNS_INTEGER2;
m_value.uint2 = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueUINT2( UINT2& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_UNS_INTEGER2 )
{
value = m_value.uint2;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueINT2( INT2 value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_INTEGER2;
m_value.int2 = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueINT2( INT2& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_INTEGER2 )
{
value = m_value.int2;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueUINT4( UINT4 value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_UNS_INTEGER4;
m_value.uint4 = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueUINT4( UINT4& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_UNS_INTEGER4 )
{
value = m_value.uint4;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueINT4( INT4 value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_INTEGER4;
m_value.int4 = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueINT4( INT4& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_INTEGER4 )
{
value = m_value.int4;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueBOOL4( bool value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_BOOLEAN4;
m_value.bool4 = value ? (BOOL4) 1 : (BOOL4) 0;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueBOOL4( bool& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_BOOLEAN4 )
{
value = ( m_value.bool4 != 0 ) ? true : false;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueREAL4( REAL4 value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_REAL4;
m_value.real4 = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueREAL4( REAL4& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_REAL4 )
{
value = m_value.real4;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueREAL8( REAL8 value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_REAL8;
m_value.real8 = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueREAL8( REAL8& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_REAL8 )
{
value = m_value.real8;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueCOMPLEX8( COMPLEX8 value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_COMPLEX8;
m_value.complex8 = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueCOMPLEX8( COMPLEX8& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_COMPLEX8 )
{
value = m_value.complex8;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueCOMPLEX16( COMPLEX16 value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_COMPLEX16;
m_value.complex16 = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueCOMPLEX16( COMPLEX16& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_COMPLEX16 )
{
value = m_value.complex16;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueGUID( GUID value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_GUID;
m_value.guid = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueGUID( GUID& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_GUID )
{
value = m_value.guid;
status = true;
}
return status;
}
bool CPQDIF_E_Scalar::SetValueTimeStamp( TIMESTAMPPQDIF value )
{
bool status = false;
m_typePhysical = ID_PHYS_TYPE_TIMESTAMPPQDIF;
m_value.ts = value;
status = true;
return status;
}
bool CPQDIF_E_Scalar::GetValueTimeStamp( TIMESTAMPPQDIF& value ) const
{
bool status = false;
if( m_typePhysical == ID_PHYS_TYPE_TIMESTAMPPQDIF )
{
value = m_value.ts;
status = true;
}
return status;
}

View File

@@ -0,0 +1,61 @@
// File name: $Workfile: el_scal.h $
// Last modified: $Modtime: 11/13/00 2:41p $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/el_scal.h $
// VCS revision: $Revision: 8 $
class CPQDIF_E_Scalar : public CPQDIF_Element
{
public:
CPQDIF_E_Scalar();
virtual ~CPQDIF_E_Scalar();
// Operator(s)
public:
// Attributes
public:
virtual long GetElementType( void ) const
{ return ID_ELEMENT_TYPE_SCALAR; }
// Operations
public:
#ifdef PQDIF_USE_COM
bool SetValue( long typePhysical, VARIANT & value );
bool GetValue( VARIANT& value );
#endif
bool SetValue( long typePhysical, PQDIFValue& value );
bool GetValue( long& typePhysical, PQDIFValue& value ) const;
// Specific physical types
bool SetValueUINT2( UINT2 value );
bool GetValueUINT2( UINT2& value ) const;
bool SetValueINT2( INT2 value );
bool GetValueINT2( INT2& value ) const;
bool SetValueUINT4( UINT4 value );
bool GetValueUINT4( UINT4& value ) const;
bool SetValueINT4( INT4 value );
bool GetValueINT4( INT4& value ) const;
bool SetValueBOOL4( bool value );
bool GetValueBOOL4( bool& value ) const;
bool SetValueREAL4( REAL4 value );
bool GetValueREAL4( REAL4& value ) const;
bool SetValueREAL8( REAL8 value );
bool GetValueREAL8( REAL8& value ) const;
bool SetValueCOMPLEX8( COMPLEX8 value );
bool GetValueCOMPLEX8( COMPLEX8& value ) const;
bool SetValueCOMPLEX16( COMPLEX16 value );
bool GetValueCOMPLEX16( COMPLEX16& value ) const;
bool SetValueGUID( GUID value );
bool GetValueGUID( GUID& value ) const;
bool SetValueTimeStamp( TIMESTAMPPQDIF value );
bool GetValueTimeStamp( TIMESTAMPPQDIF& value ) const;
// Implementation
private:
// Member data
private:
PQDIFValue m_value;
};

View File

@@ -0,0 +1,431 @@
/*
** CPQDIF_E_Vector class. Implements the PQDIF vector element.
** --------------------------------------------------------------------------
**
** File name: $Workfile: el_vect.cpp $
** Last modified: $Modtime: 11/13/00 3:56p $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/el_vect.cpp $
** VCS revision: $Revision: 14 $
*/
#include "PQDIF_classes.h"
const int defaultGrowBy = 4;
// Construction
// ============
CPQDIF_E_Vector::CPQDIF_E_Vector()
{
m_array.SetSize( 0, defaultGrowBy );
}
CPQDIF_E_Vector::~CPQDIF_E_Vector()
{
}
void CPQDIF_E_Vector::SetPhysicalType( long type )
{
long count = m_array.GetSize() / getNumBytesOfType();
if( m_typePhysical != type )
{
// Yup, it's changed!
m_typePhysical = type;
// ... and realloc space for the new type.
SetCount( count );
// Signal that the record changed.
if( m_pRecord )
m_pRecord->SetChanged( true );
}
}
#ifdef PQDIF_USE_COM
bool CPQDIF_E_Vector::SetValue( long index, VARIANT & value )
{
bool status = false;
PQDIFValue valPQ;
// Copy over the information
status = convertFromVariant( value, valPQ );
if( status )
{
SetValue( index, valPQ );
}
return status;
}
bool CPQDIF_E_Vector::GetValue( long index, VARIANT & value ) const
{
bool status = false;
PQDIFValue valPQ;
long nItem;
GetCount(nItem);
if( index >= 0 && index < nItem )
{
status = GetValue( index, valPQ );
if( status )
{
status = convertToVariant( valPQ, value );
}
}
return status;
}
#endif
bool CPQDIF_E_Vector::SetValue( long index, const PQDIFValue& value )
{
bool status = false;
BYTE * pvalSource = (BYTE *) getPointerToValue( value );
BYTE * pvalTarget = (BYTE *) getPointer( index );
if( pvalSource && pvalTarget )
{
memcpy( pvalTarget, pvalSource, getNumBytesOfType() );
status = true;
}
return status;
}
bool CPQDIF_E_Vector::GetValue( long index, PQDIFValue& value ) const
{
bool status = false;
BYTE * pvalTarget = (BYTE *) getPointerToValue( value );
BYTE * pvalSource = (BYTE *) getPointer( index );
if( pvalSource && pvalTarget )
{
memcpy( pvalTarget, pvalSource, getNumBytesOfType() );
status = true;
}
return status;
}
bool CPQDIF_E_Vector::SetValue( long index, double value )
{
bool status;
PQDIFValue valuePQ;
status = convertFromDouble( value, valuePQ );
if( status )
{
status = SetValue( index, valuePQ );
}
return status;
}
bool CPQDIF_E_Vector::GetValue( long index, double& value ) const
{
bool status;
PQDIFValue valuePQ;
status = GetValue( index, valuePQ );
if( status )
{
status = convertToDouble( valuePQ, value );
}
return status;
}
bool CPQDIF_E_Vector::SetValues( const char * text )
{
bool status = false;
long idxItem;
long countItems;
BYTE * data = NULL;
// Init
countItems = strlen( text ) + 1;
switch( GetPhysicalType() )
{
case ID_PHYS_TYPE_CHAR1:
SetCount( countItems );
data = GetRawData();
if( data )
{
// Copy the string across directly
memcpy( data, text, countItems - 1 );
// Make sure it's null-terminated
data[ countItems - 1 ] = (BYTE) 0;
status = true;
}
break;
case ID_PHYS_TYPE_CHAR2:
SetCount( countItems );
data = GetRawData();
if( data )
{
CHAR2 * temp = (CHAR2 *) data;
// Copy the data across by physical item size
// Don't copy the last character -- should be a NULL
for( idxItem = 0; idxItem < ( countItems - 1); idxItem++ )
{
// Copy each value
*temp = (CHAR2) text[ (int) idxItem ];
temp++;
}
// NULL-terminate it
*temp = (CHAR2) 0;
status = true;
}
break;
default:
status = false;
break;
}
return status;
}
bool CPQDIF_E_Vector::GetValues( string& strOutput ) const
{
bool status = false;
long idxItem;
long countItems;
const BYTE * data = NULL;
// Init
GetCount( countItems );
data = GetRawData();
switch( GetPhysicalType() )
{
case ID_PHYS_TYPE_CHAR1:
if( data )
{
// Copy the data across by physical item size
// Don't copy the last character -- should be a NULL
strOutput = (const char *) data;
status = TRUE;
}
break;
case ID_PHYS_TYPE_CHAR2:
if( data )
{
CHAR2 * temp = (CHAR2 *) data;
// Copy the data across by physical item size
// Don't copy the last character -- should be a NULL
for( idxItem = 0; idxItem < ( countItems - 1); idxItem++ )
{
// Copy across a single value
strOutput += (TCHAR) ( *temp );
// Next!
temp++;
}
status = TRUE;
}
break;
default:
status = false;
break;
}
return status;
}
BYTE * CPQDIF_E_Vector::GetRawData( void )
{
return m_array.GetData();
}
const BYTE * CPQDIF_E_Vector::GetRawData( void ) const
{
return m_array.GetData();
}
bool CPQDIF_E_Vector::GetCount( long& count ) const
{
bool status = false;
count = m_array.GetSize() / getNumBytesOfType();
status = true;
return status;
}
bool CPQDIF_E_Vector::SetCount( long count )
{
bool status = false;
// Resize the array.
int size = count * getNumBytesOfType();
m_array.SetSize( size, defaultGrowBy );
status = m_array.GetSize() == size;
return status;
}
long CPQDIF_E_Vector::GetSizeBytes( void )
{
return m_array.GetSize();
}
BYTE * CPQDIF_E_Vector::getPointer( int idx )
{
BYTE * ptr = NULL;
long count = m_array.GetSize() / getNumBytesOfType();
ptr = m_array.GetData();
if( ptr && idx >= 0 && idx < count )
{
ptr += ( idx * getNumBytesOfType() );
}
return ptr;
}
const BYTE * CPQDIF_E_Vector::getPointer( int idx ) const
{
const BYTE * ptr = NULL;
long count = m_array.GetSize() / getNumBytesOfType();
ptr = m_array.GetData();
if( ptr && idx >= 0 && idx < count )
{
ptr += ( idx * getNumBytesOfType() );
}
return ptr;
}
// Type-specific member functions
// ------------------------------
#define ELVECT_SETVALUE( nametype, type, idtype ) \
void CPQDIF_E_Vector::SetValue##nametype( long index, type value ) \
{ \
bool status = false; \
type * pval = NULL; \
SetPhysicalType( idtype ); \
pval = (type *) getPointer( index ); \
if( pval ) \
{ \
*pval = value; \
status = true; \
} \
}
#define ELVECT_GETVALUE( nametype, type, idtype ) \
bool CPQDIF_E_Vector::GetValue##nametype( long index, type& value ) const \
{ bool status = false; \
type * pval = NULL; \
if( GetPhysicalType() == idtype ) \
{ \
pval = (type *) getPointer( index ); \
if( pval ) \
{ \
value = *pval; \
status = true; \
} \
} \
return status; }
#define ELVECT_SETVALUES_ARRAY( nametype, type, idtype ) \
void CPQDIF_E_Vector::SetValues##nametype( const type * values, long count ) \
{ bool status = false; \
type * pval = NULL; \
SetPhysicalType( idtype ); \
SetCount( count ); \
pval = (type *) getPointer( 0 ); \
if( pval ) \
{ \
memcpy( pval, values, count * sizeof( type ) ); \
status = true; \
} \
}
#define ELVECT_GETVALUES_ARRAY( nametype, type, idtype ) \
long CPQDIF_E_Vector::GetValues##nametype( type * values, long max ) const \
{ long countActual = 0; \
type * pval = NULL; \
long sizeType = getNumBytesOfType(); \
long count = m_array.GetSize() / sizeType; \
if( GetPhysicalType() == idtype ) \
{ \
pval = (type *) getPointer( 0 ); \
if( pval ) \
{ \
countActual = min( max, count ); \
memcpy( values, pval, countActual * sizeType ); \
} \
} \
return countActual; }
ELVECT_SETVALUE ( INT1, INT1, ID_PHYS_TYPE_INTEGER1 )
ELVECT_SETVALUES_ARRAY( INT1, INT1, ID_PHYS_TYPE_INTEGER1 )
ELVECT_GETVALUE ( INT1, INT1, ID_PHYS_TYPE_INTEGER1 )
ELVECT_GETVALUES_ARRAY( INT1, INT1, ID_PHYS_TYPE_INTEGER1 )
ELVECT_SETVALUE ( INT2, INT2, ID_PHYS_TYPE_INTEGER2 )
ELVECT_SETVALUES_ARRAY( INT2, INT2, ID_PHYS_TYPE_INTEGER2 )
ELVECT_GETVALUE ( INT2, INT2, ID_PHYS_TYPE_INTEGER2 )
ELVECT_GETVALUES_ARRAY( INT2, INT2, ID_PHYS_TYPE_INTEGER2 )
ELVECT_SETVALUE ( INT4, INT4, ID_PHYS_TYPE_INTEGER4 )
ELVECT_SETVALUES_ARRAY( INT4, INT4, ID_PHYS_TYPE_INTEGER4 )
ELVECT_GETVALUE ( INT4, INT4, ID_PHYS_TYPE_INTEGER4 )
ELVECT_GETVALUES_ARRAY( INT4, INT4, ID_PHYS_TYPE_INTEGER4 )
ELVECT_SETVALUE ( UINT4, UINT4, ID_PHYS_TYPE_UNS_INTEGER4 )
ELVECT_SETVALUES_ARRAY( UINT4, UINT4, ID_PHYS_TYPE_UNS_INTEGER4 )
ELVECT_GETVALUE ( UINT4, UINT4, ID_PHYS_TYPE_UNS_INTEGER4 )
ELVECT_GETVALUES_ARRAY( UINT4, UINT4, ID_PHYS_TYPE_UNS_INTEGER4 )
ELVECT_SETVALUE ( REAL4, REAL4, ID_PHYS_TYPE_REAL4 )
ELVECT_SETVALUES_ARRAY( REAL4, REAL4, ID_PHYS_TYPE_REAL4 )
ELVECT_GETVALUE ( REAL4, REAL4, ID_PHYS_TYPE_REAL4 )
ELVECT_GETVALUES_ARRAY( REAL4, REAL4, ID_PHYS_TYPE_REAL4 )
ELVECT_SETVALUE ( REAL8, REAL8, ID_PHYS_TYPE_REAL8 )
ELVECT_SETVALUES_ARRAY( REAL8, REAL8, ID_PHYS_TYPE_REAL8 )
ELVECT_GETVALUE ( REAL8, REAL8, ID_PHYS_TYPE_REAL8 )
ELVECT_GETVALUES_ARRAY( REAL8, REAL8, ID_PHYS_TYPE_REAL8 )
ELVECT_SETVALUE ( TimeStamp, TIMESTAMPPQDIF, ID_PHYS_TYPE_TIMESTAMPPQDIF )
ELVECT_SETVALUES_ARRAY( TimeStamp, TIMESTAMPPQDIF, ID_PHYS_TYPE_TIMESTAMPPQDIF )
ELVECT_GETVALUE ( TimeStamp, TIMESTAMPPQDIF, ID_PHYS_TYPE_TIMESTAMPPQDIF )
ELVECT_GETVALUES_ARRAY( TimeStamp, TIMESTAMPPQDIF, ID_PHYS_TYPE_TIMESTAMPPQDIF )

View File

@@ -0,0 +1,87 @@
// File name: $Workfile: el_vect.h $
// Last modified: $Modtime: 11/13/00 2:39p $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/el_vect.h $
// VCS revision: $Revision: 13 $
class CPQDIF_E_Vector : public CPQDIF_Element
{
public:
CPQDIF_E_Vector();
virtual ~CPQDIF_E_Vector();
// Operator(s)
public:
// Attributes
public:
virtual long GetElementType( void ) const
{ return ID_ELEMENT_TYPE_VECTOR; }
virtual void SetPhysicalType( long type );
bool GetCount( long& count ) const;
bool SetCount( long count );
long GetSizeBytes( void );
// Operations
public:
#ifdef PQDIF_USE_COM
bool SetValue( long index, VARIANT & value );
bool GetValue( long index, VARIANT & value ) const;
#endif
bool SetValue( long index, const PQDIFValue& value );
bool GetValue( long index, PQDIFValue& value ) const;
bool SetValue( long index, double value );
bool GetValue( long index, double& value ) const;
// Specific types
void SetValueINT1 ( long idx, INT1 value );
void SetValuesINT1 ( const INT1 * array, long count );
bool GetValueINT1 ( long idx, INT1& value ) const;
long GetValuesINT1 ( INT1 * array, long max ) const;
void SetValueINT2 ( long idx, INT2 value );
void SetValuesINT2 ( const INT2 * array, long count );
bool GetValueINT2 ( long idx, INT2& value ) const;
long GetValuesINT2 ( INT2 * array, long max ) const;
void SetValueINT4 ( long idx, INT4 value );
void SetValuesINT4 ( const INT4 * array, long count );
bool GetValueINT4 ( long idx, INT4& value ) const;
long GetValuesINT4 ( INT4 * array, long max ) const;
void SetValueUINT4( long index, UINT4 value );
void SetValuesUINT4 ( const UINT4 * array, long count );
bool GetValueUINT4( long index, UINT4& value ) const;
long GetValuesUINT4 ( UINT4 * array, long max ) const;
void SetValueREAL4 ( long idx, REAL4 value );
void SetValuesREAL4 ( const REAL4 * array, long count );
bool GetValueREAL4 ( long idx, REAL4& value ) const;
long GetValuesREAL4 ( REAL4 * array, long max ) const;
void SetValueREAL8 ( long idx, REAL8 value );
void SetValuesREAL8 ( const REAL8 * array, long count );
bool GetValueREAL8 ( long idx, REAL8& value ) const;
long GetValuesREAL8 ( REAL8 * array, long max ) const;
void SetValueTimeStamp ( long idx, TIMESTAMPPQDIF value );
void SetValuesTimeStamp ( const TIMESTAMPPQDIF * array, long count );
bool GetValueTimeStamp ( long idx, TIMESTAMPPQDIF& value ) const;
long GetValuesTimeStamp ( TIMESTAMPPQDIF * array, long max ) const;
bool SetValues( const char * text );
bool GetValues( string& text ) const;
BYTE * GetRawData( void );
const BYTE * GetRawData( void ) const;
// Implementation
protected:
BYTE * getPointer( int idx );
const BYTE * getPointer( int idx ) const;
// Member data
private:
CPQByteArray m_array;
};

View File

@@ -0,0 +1,517 @@
ADD_ID_UINT4_ENTRY( ID_COMP_STYLE_NONE, tagCompressionStyleID );
ADD_ID_UINT4_ENTRY( ID_COMP_STYLE_RECORDLEVEL, tagCompressionStyleID );
ADD_ID_UINT4_ENTRY( ID_COMP_STYLE_TOTALFILE, tagCompressionStyleID );
ADD_ID_UINT4_ENTRY( ID_COMP_ALG_NONE, tagCompressionAlgorithmID );
ADD_ID_UINT4_ENTRY( ID_COMP_ALG_ZLIB, tagCompressionAlgorithmID );
ADD_ID_UINT4_ENTRY( ID_COMP_ALG_PKZIPCL, tagCompressionAlgorithmID );
ADD_ID_GUID_ENTRY( ID_DS_TYPE_MEASURE, tagDataSourceTypeID );
ADD_ID_GUID_ENTRY( ID_DS_TYPE_MANUAL, tagDataSourceTypeID );
ADD_ID_GUID_ENTRY( ID_DS_TYPE_SIMULATE, tagDataSourceTypeID );
ADD_ID_GUID_ENTRY( ID_DS_TYPE_BENCHMARK, tagDataSourceTypeID );
ADD_ID_GUID_ENTRY( ID_DS_TYPE_DEBUG, tagDataSourceTypeID );
ADD_ID_GUID_ENTRY( ID_VENDOR_SATEC, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_WPT, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_NONE, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_BMI, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_BPA, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_CESI, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_COOPER, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_DCG, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_DRANETZ, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_EDF, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_EPRI, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_ELECTROTEK, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_FLUKE, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_HYDROQUEBEC, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_IEEE, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_KREISSJOHNSON, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_METROSONIC, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_PML, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_PSI, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_PTI, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_PUBLICDOMAIN, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_RPM, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_SQUAREDPOWERLOGIC, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_TELOG, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_PMI, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_METONE, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_TRINERGI, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_GE, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_LEM, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_ACTL, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_ADVANTECH, tagVendorID );
ADD_ID_GUID_ENTRY( ID_VENDOR_ELCOM, tagVendorID );
ADD_ID_GUID_ENTRY( ID_EQUIP_WPT_5530, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_WPT_5540, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_BMI_3100, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_BMI_7100, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_BMI_8010, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_BMI_8020, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_BMI_9010, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_COOPER_VHARM, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_COOPER_VFLICKER, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_DCG_EMTP, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_DRANETZ_656, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_DRANETZ_658, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_TESTPROGRAM, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_DRANETZ_8000, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_PQDIFEDITOR, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_PASS, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_SUPERHARM, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_SUPERTRAN, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_TOP, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_PQVIEW, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_HARMONI, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_FLUKE_CUR, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_IEEE_COMTRADE, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_FLUKE_F41, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PUBLIC_ATP, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_METROSONIC_M1, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_SQD_SMS, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_TELOG_M1, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PML_3710, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PML_3720, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PML_3800, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PML_7300, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PML_7700, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PML_VIP, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PML_LOGSERVER, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_METONE_ELT15, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_PMI_SCANNER, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM4017, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_DSS, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM4018, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM4018M, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM4052, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_BMI_8800, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_TRINERGI_PQM, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_MEDCAL, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_GE_KV, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_GE_KV2, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ACUMENTRICS_CONTROL, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_TEXTPQDIF, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_PQWEB, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_QWAVE_POWER_DISTRIBUTION, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_QWAVE_POWER_TRANSMISSION, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_QWAVE_MICRO, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_QWAVE_TWIN, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_QWAVE_PREMIUM, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_QWAVE_LIGHT, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_QWAVE_NOMAD, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_EWON_4000, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_QUALIMETRE, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_ANALYST3Q, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_ANALYST1Q, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_ANALYST2050, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_ANALYST2060, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_MIDGET200, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_MBX300, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_MBX800, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_MBX601, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_MBX602, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_MBX603, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_MBX686, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_PERMA701, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_PERMA702, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_PERMA705, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_PERMA706, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_QWAVEMICRO, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_QWAVENOMAD, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_QWAVELIGHT, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_QWAVETWIN, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_QWAVEPOWER_DISTRIBUTION, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_QWAVEPREMIUM, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_QWAVEPOWER_TRANSPORT, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_TOPASLT, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_TOPAS1000, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_TOPAS1019, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_TOPAS1020, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_TOPAS1040, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_BEN5000, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_BEN6000, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_EWAVE, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_LEM_EWON4000, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_WPT_5510, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_WPT_5520, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_WPT_5530T, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_WPT_5560, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_WPT_5590, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ETK_NODECENTER, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_WPT_DRANVIEW, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM5017, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM5018, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM5080, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM5052, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM4050, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM4053, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM4080, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM5050, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ADVANTECH_ADAM5051, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_EQUIP_ELCOM_BK550, tagEquipmentID );
ADD_ID_GUID_ENTRY( ID_INSTR_TYPE_SCOPE, tagInstrumentTypeID );
ADD_ID_GUID_ENTRY( ID_INSTR_TYPE_FR, tagInstrumentTypeID );
ADD_ID_GUID_ENTRY( ID_INSTR_TYPE_PQM, tagInstrumentTypeID );
ADD_ID_GUID_ENTRY( ID_INSTR_TYPE_VR, tagInstrumentTypeID );
ADD_ID_GUID_ENTRY( ID_INSTR_TYPE_SA, tagInstrumentTypeID );
ADD_ID_UINT4_ENTRY( ID_PHASE_NONE, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_AN , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_BN , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_CN , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_NG , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_AB , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_BC , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_CA , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_RES , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_NET , tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_TOTAL, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_LN_AVE, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_LL_AVE, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_WORST, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_PLUS, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_MINUS, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_1, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_2, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_3, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_4, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_5, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_6, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_7, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_8, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_9, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_10, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_11, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_12, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_13, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_14, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_15, tagPhaseID );
ADD_ID_UINT4_ENTRY( ID_PHASE_GENERAL_16, tagPhaseID );
ADD_ID_GUID_ENTRY( ID_QT_WAVEFORM, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_VALUELOG, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_PHASOR, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_RESPONSE, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_FLASH, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_HISTOGRAM, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_HISTOGRAM3D, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_CPF, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_XY, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_MAGDUR, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_XYZ, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_MAGDURTIME, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_QT_MAGDURCOUNT, tagQuantityTypeID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_NONE, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT_IMPULSIVE, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT_IMPULSIVE_NANO, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT_IMPULSIVE_MICRO, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT_IMPULSIVE_MILLI, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT_OSCILLATORY, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT_OSCILLATORY_LOWFREQ, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT_OSCILLATORY_MEDFREQ, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_TRANSIENT_OSCILLATORY_HIGHFREQ, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_INSTANT, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_INSTANT_SAG, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_INSTANT_SWELL, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_MOMENT, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_MOMENT_INTERRUPT, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_MOMENT_SAG, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_MOMENT_SWELL, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_TEMP, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_TEMP_INTERRUPT, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_TEMP_SAG, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_SHORTDUR_TEMP_SWELL, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_LONGDUR, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_LONGDUR_INTERRUPT, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_LONGDUR_SAG, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_LONGDUR_SWELL, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_IMBALANCE, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_POWERFREQVARIATION, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_VOLTAGEFLUCTUATION, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_WAVEDISTORT, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_WAVEDISTORT_DCOFFSET, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_WAVEDISTORT_HARMONIC, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_WAVEDISTORT_INTERHARMONIC, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_WAVEDISTORT_NOTCHING, tagDisturbanceCategoryID );
ADD_ID_GUID_ENTRY( ID_DISTURB_1159_WAVEDISTORT_NOISE, tagDisturbanceCategoryID );
ADD_ID_UINT4_ENTRY( ID_QU_NONE , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_SECONDS , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_TIMESTAMP , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_CYCLES , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_VOLTS , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_AMPS , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_VA , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_WATTS , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_VARS , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_OHMS , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_SIEMENS , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_VOLTSPERAMP, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_JOULES , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_HERTZ , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_CELCIUS , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_DEGREES , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_DB , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_PERCENT , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_PERUNIT , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_SAMPLES , tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_VARHOURS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_WATTHOURS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_VAHOURS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_MPS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_MPH, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_BARS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_PASCALS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_NEWTONS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_NEWTONMETERS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_RPM, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_RADPERSEC, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_METERS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_WEBERTURNS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_TESLAS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_WEBERS, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_VOLTSPERVOLT, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_AMPSPERAMP, tagQuantityUnitsID );
ADD_ID_UINT4_ENTRY( ID_QU_AMPSPERVOLT, tagQuantityUnitsID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_VAL, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_TIME, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_MIN, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_MAX, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_AVG, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_INST, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_PHASEANGLE, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_PHASEANGLE_MIN, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_PHASEANGLE_MAX, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_PHASEANGLE_AVG, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_AREA, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_LATITUDE, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_DURATION, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_LONGITUDE, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_POLARITY, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_ELLIPSE, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_BINID, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_BINHIGH, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_BINLOW, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_XBINHIGH, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_XBINLOW, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_YBINHIGH, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_YBINLOW, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_COUNT, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_TRANSITION, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_PROB, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_INTERVAL, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_STATUS, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_P1, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_P5, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_P10, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_P90, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_P95, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_P99, tagValueTypeID );
ADD_ID_GUID_ENTRY( ID_SERIES_VALUE_TYPE_FREQUENCY, tagValueTypeID );
ADD_ID_UINT4_ENTRY( ID_SERIES_METHOD_VALUES , tagStorageMethodID );
ADD_ID_UINT4_ENTRY( ID_SERIES_METHOD_SCALED, tagStorageMethodID );
ADD_ID_UINT4_ENTRY( ID_SERIES_METHOD_INCREMENT, tagStorageMethodID );
ADD_ID_UINT4_ENTRY( ID_GREEK_DONTCARE, tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_FEMTO , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_PICO , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_NANO , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_MICRO , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_MILLI , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_NONE , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_KILO , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_MEGA , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_TERA, tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_GREEK_GIGA , tagHintGreekPrefixID );
ADD_ID_UINT4_ENTRY( ID_PREFER_ENG, tagHintPreferredUnitsID );
ADD_ID_UINT4_ENTRY( ID_PREFER_PCT, tagHintPreferredUnitsID );
ADD_ID_UINT4_ENTRY( ID_PREFER_PU , tagHintPreferredUnitsID );
ADD_ID_UINT4_ENTRY( ID_DEFAULT_DONTCARE, tagHintDefaultDisplayID );
ADD_ID_UINT4_ENTRY( ID_DEFAULT_MAG , tagHintDefaultDisplayID );
ADD_ID_UINT4_ENTRY( ID_DEFAULT_ANG , tagHintDefaultDisplayID );
ADD_ID_UINT4_ENTRY( ID_DEFAULT_REAL , tagHintDefaultDisplayID );
ADD_ID_UINT4_ENTRY( ID_DEFAULT_IMAG, tagHintDefaultDisplayID );
ADD_ID_UINT4_ENTRY( ID_DEFAULT_RX, tagHintDefaultDisplayID );
ADD_ID_UINT4_ENTRY( ID_TRIG_NONE , tagTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_TRIG_LOW , tagTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_TRIG_HIGH , tagTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_TRIG_RATE , tagTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_TRIG_SHAPE, tagTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_TRIG_OTHER, tagTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_XFORMER_TYPE_CT, tagXDTransformerTypeID );
ADD_ID_UINT4_ENTRY( ID_XFORMER_TYPE_PT, tagXDTransformerTypeID );
ADD_ID_UINT4_ENTRY( ID_TRIGGER_METH_NONE, tagTriggerMethodID );
ADD_ID_UINT4_ENTRY( ID_TRIGGER_METH_CHANNEL, tagTriggerMethodID );
ADD_ID_UINT4_ENTRY( ID_TRIGGER_METH_PERIODIC, tagTriggerMethodID );
ADD_ID_UINT4_ENTRY( ID_TRIGGER_METH_EXTERNAL, tagTriggerMethodID );
ADD_ID_UINT4_ENTRY( ID_TRIGGER_METH_PERIODIC_STATS, tagTriggerMethodID );
ADD_ID_GUID_ENTRY( ID_QC_NONE, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_INSTANTANEOUS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_SPECTRA, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_PEAK, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_RMS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_HRMS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FREQUENCY, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_TOTAL_THD, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_EVEN_THD, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_ODD_THD, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_CREST_FACTOR, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FORM_FACTOR, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_ARITH_SUM, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S0S1, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S2S1, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_SPOS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_SNEG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_SZERO, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_AVG_IMBAL, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_TOTAL_THD_RMS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_ODD_THD_RMS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_EVEN_THD_RMS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_TID, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_TID_RMS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_IHRMS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_SPECTRA_HGROUP, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_SPECTRA_IGROUP, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_TIF, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_MAG_AVG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_MAX_DVV, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_FREQ_MAX, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_MAG_MAX, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_WGT_AVG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_SPECTRUM, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_PST, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_PLT, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_TIF_RMS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_PLTSLIDE, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_PILPF, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_PIMAX, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_PIROOT, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_FLKR_PIROOTLPF, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_IT, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_RMS_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_ANSI_TDF, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_K_FACTOR, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_TDD, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_RMS_PEAK_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_PF, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_DF, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_DF_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_PF_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_PRED_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_PRED_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_PRED_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_CO_Q_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_CO_S_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_CO_P_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_CO_S_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_DF_CO_S_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_PF_CO_S_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_PF_CO_P_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_PF_CO_Q_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_ANGLE_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_PF_VECTOR, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_DF_VECTOR, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_VECTOR, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_VECTOR_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_CO_P_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_CO_Q_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_PF_ARITH, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_DF_ARITH, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_ARITH, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_ARITH_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_PEAK_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_PEAK_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_PEAK_DEMAND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_HARMONIC, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_HARMONIC_UNSIGNED, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_INTG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_INTG_POS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_INTG_POS_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_INTG_NEG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_INTG_NEG_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_INTG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_INTG_POS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_INTG_POS_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_INTG_NEG_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_INTG_NEG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_INTG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_INTG_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_IVL_INTG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_IVL_INTG_POS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_IVL_INTG_POS_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_IVL_INTG_NEG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_P_IVL_INTG_NEG_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_IVL_INTG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_IVL_INTG_POS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_IVL_INTG_POS_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_IVL_INTG_NEG_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_Q_IVL_INTG_NEG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_IVL_INTG, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_S_IVL_INTG_FUND, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_DAXISFIELD, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_QAXIS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_ROTATIONAL, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_DAXIS, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_LINEAR, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_TRANSFERFUNC, tagQuantityCharacteristicID );
ADD_ID_GUID_ENTRY( ID_QC_STATUS, tagQuantityCharacteristicID );
ADD_ID_UINT4_ENTRY( ID_QM_NONE, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_VOLTAGE, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_CURRENT, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_POWER, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_ENERGY, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_TEMPERATURE, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_PRESSURE, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_CHARGE, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_EFIELD, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_MFIELD, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_VELOCITY, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_BEARING, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_FORCE, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_TORQUE, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_POSITION, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_FLUXLINKAGE, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_FLUXDENSITY, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_QM_STATUS, tagQuantityMeasuredID );
ADD_ID_UINT4_ENTRY( ID_CTT_NONE, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_NORMAL_TO_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_NORMAL_TO_LO_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_NORMAL_TO_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_NORMAL_TO_HI_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_LO_LO_TO_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_LO_LO_TO_NORMAL, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_LO_LO_TO_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_LO_LO_TO_HI_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_LO_TO_LO_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_LO_TO_NORMAL, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_LO_TO_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_LO_TO_HI_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_HI_TO_LO_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_HI_TO_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_HI_TO_NORMAL, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_HI_TO_HI_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_HI_HI_TO_LO_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_HI_HI_TO_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_HI_HI_TO_NORMAL, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_HI_HI_TO_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_DB_LO, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_DB_HI, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_PERIODIC, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_MANUAL, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_INT_CROSS_TRIG, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_EXT_CROSS_TRIG, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_MODULE, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_CTT_RATE, tagChanTriggerTypeID );
ADD_ID_UINT4_ENTRY( ID_SINGLE_PHASE, tagSettingPhysicalConnection );
ADD_ID_UINT4_ENTRY( ID_2ELEMENT_DELTA, tagSettingPhysicalConnection );
ADD_ID_UINT4_ENTRY( ID_2_5ELEMENT_WYE, tagSettingPhysicalConnection );
ADD_ID_UINT4_ENTRY( ID_3ELMENT_WYE, tagSettingPhysicalConnection );
ADD_ID_UINT4_ENTRY( ID_3ELEMENT_DELTA, tagSettingPhysicalConnection );
ADD_ID_UINT4_ENTRY( ID_SPLIT_PHASE, tagSettingPhysicalConnection );
ADD_ID_UINT4_ENTRY( ID_2ELEMENT_2PHASE, tagSettingPhysicalConnection );

View File

@@ -0,0 +1,136 @@
ADD_TAG_ENTRY( tagContainer );
ADD_TAG_ENTRY( tagRecDataSource );
ADD_TAG_ENTRY( tagRecMonitorSettings );
ADD_TAG_ENTRY( tagRecObservation );
ADD_TAG_ENTRY( tagVersionInfo );
ADD_TAG_ENTRY( tagFileName );
ADD_TAG_ENTRY( tagCreation );
ADD_TAG_ENTRY( tagLastSaved );
ADD_TAG_ENTRY( tagTimesSaved );
ADD_TAG_ENTRY( tagLanguage );
ADD_TAG_ENTRY( tagTitle );
ADD_TAG_ENTRY( tagSubject );
ADD_TAG_ENTRY( tagAuthor );
ADD_TAG_ENTRY( tagKeywords );
ADD_TAG_ENTRY( tagComments );
ADD_TAG_ENTRY( tagLastSavedBy );
ADD_TAG_ENTRY( tagApplication );
ADD_TAG_ENTRY( tagSecurity );
ADD_TAG_ENTRY( tagOwner );
ADD_TAG_ENTRY( tagCopyright );
ADD_TAG_ENTRY( tagTrademarks );
ADD_TAG_ENTRY( tagNotes );
ADD_TAG_ENTRY( tagCompressionStyleID );
ADD_TAG_ENTRY( tagCompressionAlgorithmID );
ADD_TAG_ENTRY( tagCompressionChecksum );
ADD_TAG_ENTRY( tagName );
ADD_TAG_ENTRY( tagAddress1 );
ADD_TAG_ENTRY( tagAddress2 );
ADD_TAG_ENTRY( tagCity );
ADD_TAG_ENTRY( tagState );
ADD_TAG_ENTRY( tagPostalCode );
ADD_TAG_ENTRY( tagCountry );
ADD_TAG_ENTRY( tagPhoneVoice );
ADD_TAG_ENTRY( tagPhoneFAX );
ADD_TAG_ENTRY( tagEMail );
ADD_TAG_ENTRY( tagDataSourceTypeID );
ADD_TAG_ENTRY( tagVendorID );
ADD_TAG_ENTRY( tagEquipmentID );
ADD_TAG_ENTRY( tagCustomSourceInfo );
ADD_TAG_ENTRY( tagSerialNumberDS );
ADD_TAG_ENTRY( tagVersionDS );
ADD_TAG_ENTRY( tagNameDS );
ADD_TAG_ENTRY( tagOwnerDS );
ADD_TAG_ENTRY( tagLocationDS );
ADD_TAG_ENTRY( tagTimeZoneDS );
ADD_TAG_ENTRY( tagCoordinatesDS );
ADD_TAG_ENTRY( tagChannelDefns );
ADD_TAG_ENTRY( tagInstrumentTypeID );
ADD_TAG_ENTRY( tagInstrumentModelName );
ADD_TAG_ENTRY( tagInstrumentModelNumber );
ADD_TAG_ENTRY( tagOneChannelDefn );
ADD_TAG_ENTRY( tagChannelName );
ADD_TAG_ENTRY( tagPhaseID );
ADD_TAG_ENTRY( tagOtherChannelIdentifier );
ADD_TAG_ENTRY( tagGroupName );
ADD_TAG_ENTRY( tagQuantityTypeID );
ADD_TAG_ENTRY( tagQuantityMeasuredID );
ADD_TAG_ENTRY( tagPhysicalChannel );
ADD_TAG_ENTRY( tagQuantityName );
ADD_TAG_ENTRY( tagPrimarySeriesIdx );
ADD_TAG_ENTRY( tagSeriesDefns );
ADD_TAG_ENTRY( tagOneSeriesDefn );
ADD_TAG_ENTRY( tagValueTypeID );
ADD_TAG_ENTRY( tagQuantityUnitsID );
ADD_TAG_ENTRY( tagQuantityCharacteristicID );
ADD_TAG_ENTRY( tagQuantitySignificantDigitsID );
ADD_TAG_ENTRY( tagQuantityResolutionID );
ADD_TAG_ENTRY( tagStorageMethodID );
ADD_TAG_ENTRY( tagValueTypeName );
ADD_TAG_ENTRY( tagHintGreekPrefixID );
ADD_TAG_ENTRY( tagHintPreferredUnitsID );
ADD_TAG_ENTRY( tagHintDefaultDisplayID );
ADD_TAG_ENTRY( tagProbInterval );
ADD_TAG_ENTRY( tagProbPercentile );
ADD_TAG_ENTRY( tagSeriesNominalQuantity );
ADD_TAG_ENTRY( tagEffective );
ADD_TAG_ENTRY( tagTimeInstalled );
ADD_TAG_ENTRY( tagTimeRemoved );
ADD_TAG_ENTRY( tagUseCalibration );
ADD_TAG_ENTRY( tagUseTransducer );
ADD_TAG_ENTRY( tagChannelSettingsArray );
ADD_TAG_ENTRY( tagNominalFrequency );
ADD_TAG_ENTRY( tagSettingPhysicalConnection );
ADD_TAG_ENTRY( tagOneChannelSetting );
ADD_TAG_ENTRY( tagChannelDefnIdx );
ADD_TAG_ENTRY( tagTriggerTypeID );
ADD_TAG_ENTRY( tagFullScale );
ADD_TAG_ENTRY( tagNoiseFloor );
ADD_TAG_ENTRY( tagTriggerShapeParam );
ADD_TAG_ENTRY( tagXDTransformerTypeID );
ADD_TAG_ENTRY( tagXDSystemSideRatio );
ADD_TAG_ENTRY( tagXDMonitorSideRatio );
ADD_TAG_ENTRY( tagXDFrequencyResponse );
ADD_TAG_ENTRY( tagCalTimeSkew );
ADD_TAG_ENTRY( tagCalOffset );
ADD_TAG_ENTRY( tagCalRatio );
ADD_TAG_ENTRY( tagCalMustUseARCal );
ADD_TAG_ENTRY( tagCalApplied );
ADD_TAG_ENTRY( tagCalRecorded );
ADD_TAG_ENTRY( tagTriggerHighHigh );
ADD_TAG_ENTRY( tagTriggerHigh );
ADD_TAG_ENTRY( tagTriggerLow );
ADD_TAG_ENTRY( tagTriggerLowLow );
ADD_TAG_ENTRY( tagTriggerDeadBand );
ADD_TAG_ENTRY( tagTriggerRate );
ADD_TAG_ENTRY( tagObservationName );
ADD_TAG_ENTRY( tagTimeCreate );
ADD_TAG_ENTRY( tagTimeStart );
ADD_TAG_ENTRY( tagTriggerMethodID );
ADD_TAG_ENTRY( tagTimeTriggered );
ADD_TAG_ENTRY( tagChannelTriggerIdx );
ADD_TAG_ENTRY( tagObservationSerial );
ADD_TAG_ENTRY( tagObservationAggregationSerial );
ADD_TAG_ENTRY( tagDisturbanceCategoryID );
ADD_TAG_ENTRY( tagChannelInstances );
ADD_TAG_ENTRY( tagCharactDisturbDirection );
ADD_TAG_ENTRY( tagCharactDisturbDirectionQuality );
ADD_TAG_ENTRY( tagOneChannelInst );
ADD_TAG_ENTRY( tagCharactDuration );
ADD_TAG_ENTRY( tagSeriesInstances );
ADD_TAG_ENTRY( tagCharactMagnitude );
ADD_TAG_ENTRY( tagCharactFrequency );
ADD_TAG_ENTRY( tagChanTriggerModuleInfo );
ADD_TAG_ENTRY( tagChanTriggerModuleName );
ADD_TAG_ENTRY( tagCrossTriggerDeviceName );
ADD_TAG_ENTRY( tagCrossTriggerChanIdx );
ADD_TAG_ENTRY( tagChanTriggerTypeID );
ADD_TAG_ENTRY( tagChannelFrequency );
ADD_TAG_ENTRY( tagChannelGroupID );
ADD_TAG_ENTRY( tagOneSeriesInstance );
ADD_TAG_ENTRY( tagSeriesBaseQuantity );
ADD_TAG_ENTRY( tagSeriesScale );
ADD_TAG_ENTRY( tagSeriesOffset );
ADD_TAG_ENTRY( tagSeriesShareChannelIdx );
ADD_TAG_ENTRY( tagSeriesShareSeriesIdx );
ADD_TAG_ENTRY( tagSeriesValues );

View File

@@ -0,0 +1,385 @@
/*
** CPQDIF_PersistController class. The base class for persistence controller
** classes. These classes are used to control how the PQDIF data is stored
** and retrieved from a particular medium.
** --------------------------------------------------------------------------
**
** File name: $Workfile: pcn_base.cpp $
** Last modified: $Modtime: 7/07/99 5:08p $
** Last modified by: $Author: Erich $
**
** VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/pcn_base.cpp $
** VCS revision: $Revision: 9 $
*/
#include "PQDIF_classes.h"
// Construction
// ============
CPQDIF_PersistController::CPQDIF_PersistController()
{
m_arrayRecords.SetSize( 0, 8 );
m_state = pqpc_Empty;
}
CPQDIF_PersistController::~CPQDIF_PersistController()
{
CPQDIFRecord * prec = NULL;
// Delete record objects in array
for( int idx = 0; idx < m_arrayRecords.GetSize(); idx++ )
{
prec = (CPQDIFRecord *)(m_arrayRecords[ idx ]);
delete prec;
}
}
CPQDIFRecord * CPQDIF_PersistController::GetRecord( long index )
{
CPQDIFRecord * prec = NULL;
if( index >= 0 && index < m_arrayRecords.GetSize() )
{
prec = (CPQDIFRecord *) m_arrayRecords[ index ];
}
return prec;
}
long CPQDIF_PersistController::GetRecordCount( void ) const
{
return m_arrayRecords.GetSize();
}
bool CPQDIF_PersistController::InsertRecord( CPQDIFRecord * prec, long indexToInsert )
{
bool status = FALSE;
if( indexToInsert >= 0 && indexToInsert <= m_arrayRecords.GetSize() )
{
m_arrayRecords.InsertAt( indexToInsert, prec );
status = TRUE;
}
return status;
}
bool CPQDIF_PersistController::RemoveRecord( long index )
{
bool status = FALSE;
CPQDIFRecord * prec = NULL;
if( index >= 0 && index < m_arrayRecords.GetSize() )
{
m_arrayRecords.RemoveAt( index );
status = TRUE;
}
return status;
}
long CPQDIF_PersistController::CreateContainerRecord
(
const char * language,
const char * title,
const char * subject,
const char * author,
const char * keywords,
const char * comments,
const char * lastSavedBy,
const char * application,
const char * security,
const char * owner,
const char * copyright,
const char * trademarks,
const char * notes
)
{
CPQDIFRecord * prec;
long idxNewRecord = 0;
CPQDIF_E_Collection * pcollMain;
prec = theFactory.NewRecord( PFR_Container );
if( prec )
{
// Create main collection for new record
pcollMain = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollMain )
{
// Add string entries
pcollMain->SetVectorString( tagLanguage, language );
pcollMain->SetVectorString( tagTitle, title );
pcollMain->SetVectorString( tagSubject, subject );
pcollMain->SetVectorString( tagAuthor, author );
pcollMain->SetVectorString( tagKeywords, keywords );
pcollMain->SetVectorString( tagComments, comments );
pcollMain->SetVectorString( tagLastSavedBy, lastSavedBy );
pcollMain->SetVectorString( tagApplication, application );
pcollMain->SetVectorString( tagSecurity, security );
pcollMain->SetVectorString( tagOwner, owner );
pcollMain->SetVectorString( tagCopyright, copyright );
pcollMain->SetVectorString( tagTrademarks, trademarks );
pcollMain->SetVectorString( tagNotes, notes );
// Hand it over to the record object
prec->SetMainCollection( pcollMain );
// Stuff the record into the first slot
m_arrayRecords.SetAtGrow( 0, prec );
}
}
return idxNewRecord;
}
long CPQDIF_PersistController::CreateContainerRecord
(
const char * szFileName,
const TIMESTAMPPQDIF * timeCreate,
const long lMajor,
const long lMinor,
const long lCompatMajor,
const long lCompatMinor
)
{
CPQDIFRecord * prec;
long idxNewRecord = 0;
CPQDIF_E_Collection * pcollMain;
prec = theFactory.NewRecord( PFR_Container );
if( prec )
{
// Create main collection for new record
pcollMain = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollMain )
{
// Add string entries
pcollMain->SetVectorString( tagFileName, szFileName );
pcollMain->SetScalarTimeStamp( tagCreation, *timeCreate );
UINT4 aVer[4];
aVer[0] = lMajor;
aVer[1] = lMinor;
aVer[2] = lCompatMajor;
aVer[3] = lCompatMinor;
pcollMain->SetVectorUINT4( tagVersionInfo, aVer, 4 );
// Hand it over to the record object
prec->SetMainCollection( pcollMain );
// Stuff the record into the first slot
m_arrayRecords.SetAtGrow( 0, prec );
}
}
return idxNewRecord;
}
long CPQDIF_PersistController::CreateDataSourceRecord
(
long indexInsert,
const GUID& idDataSourceType,
const GUID& idVendor,
const GUID& idEquipment,
const char * serialNumberDS, // Optional (can be NULL)
const char * versionDS, // Optional
const char * nameDS,
const char * ownerDS, // Optional
const char * locationDS, // Optional
const char * timeZoneDS // Optional
)
{
CPQDIFRecord * prec;
long idxNewRecord = indexInsert; // Is this right? need to fix
CPQDIF_E_Collection * pcollMain;
CPQDIF_E_Collection * pcollDefinitions;
prec = theFactory.NewRecord( PFR_DataSource );
if( prec )
{
// Create main collection for new record
pcollMain = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollMain )
{
// Add GUID & string entries
pcollMain->SetScalarGUID( tagDataSourceTypeID, idDataSourceType );
pcollMain->SetScalarGUID( tagVendorID, idVendor );
pcollMain->SetScalarGUID( tagEquipmentID, idEquipment );
pcollMain->SetVectorString( tagSerialNumberDS, serialNumberDS );
pcollMain->SetVectorString( tagVersionDS, versionDS );
pcollMain->SetVectorString( tagNameDS, nameDS );
pcollMain->SetVectorString( tagOwnerDS, ownerDS );
pcollMain->SetVectorString( tagLocationDS, locationDS );
pcollMain->SetVectorString( tagTimeZoneDS, timeZoneDS );
// Insert an empty collection ...
pcollDefinitions = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
pcollDefinitions->SetTag( tagChannelDefns );
pcollMain->Add( pcollDefinitions );
// Hand it over to the record object
prec->SetMainCollection( pcollMain );
// Add the record
InsertRecord( prec, indexInsert );
}
}
return idxNewRecord;
}
long CPQDIF_PersistController::CreateMonitorSettingsRecord
(
long indexInsert,
const TIMESTAMPPQDIF * timeEffective,
const TIMESTAMPPQDIF * timeInstalled,
const TIMESTAMPPQDIF * timeRemoved,
bool useCal,
bool useTrans
)
{
long idxNewRecord = indexInsert; // Is this right? need to fix
CPQDIF_R_Settings * prec;
CPQDIF_E_Collection * pcollMain;
prec = (CPQDIF_R_Settings *) theFactory.NewRecord( PFR_MonitorSettings );
if( prec )
{
// Create main collection for new record
pcollMain = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollMain )
{
prec->SetMainCollection( pcollMain );
prec->SetInfo( *timeEffective,
*timeInstalled,
*timeRemoved,
useCal,
useTrans );
// Add the record
InsertRecord( prec, indexInsert );
}
}
return idxNewRecord;
}
long CPQDIF_PersistController::CreateMonitorSettingsRecord
(
long indexInsert
)
{
long idxNewRecord = indexInsert; // Is this right? need to fix
CPQDIF_R_Settings * prec;
CPQDIF_E_Collection * pcollMain;
prec = (CPQDIF_R_Settings *) theFactory.NewRecord( PFR_MonitorSettings );
if( prec )
{
// Create main collection for new record
pcollMain = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollMain )
{
prec->SetMainCollection( pcollMain );
// Add the record
InsertRecord( prec, indexInsert );
}
}
return idxNewRecord;
}
long CPQDIF_PersistController::CreateObservationRecord
(
long indexInsert,
const char * name,
const TIMESTAMPPQDIF * timeCreate,
const TIMESTAMPPQDIF * timeStart,
UINT4 idTriggerMethod,
const TIMESTAMPPQDIF * timeTriggered, // Optional (can be NULL)
long countTriggers,
UINT4 * aidxChannelTrigger // Array of channel indices[ countTriggers ]
// Optional (can be NULL)
)
{
CPQDIFRecord * prec;
long idxNewRecord = indexInsert; // Is this right? need to fix
CPQDIF_E_Collection * pcollMain;
CPQDIF_E_Collection * pcollInstances;
// Triggers
long idxTrigger;
CPQDIF_E_Vector * pvectChannelIdx;
PQDIFValue valuePQDIF;
// Create and populate the new record
prec = theFactory.NewRecord( PFR_Observation );
if( prec )
{
// Create main collection for new record
pcollMain = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollMain )
{
// Add entries
pcollMain->SetVectorString( tagObservationName, name );
pcollMain->SetScalarTimeStamp( tagTimeCreate, *timeCreate );
pcollMain->SetScalarTimeStamp( tagTimeStart, *timeStart );
pcollMain->SetScalarUINT4( tagTriggerMethodID, idTriggerMethod );
// Optional time triggered
if( timeTriggered )
{
pcollMain->SetScalarTimeStamp( tagTimeTriggered, *timeTriggered );
}
// Optional triggers
if( countTriggers > 0 && aidxChannelTrigger )
{
pvectChannelIdx = (CPQDIF_E_Vector *) theFactory.NewElement( ID_ELEMENT_TYPE_VECTOR );
if( pvectChannelIdx )
{
pvectChannelIdx->SetTag( tagChannelTriggerIdx );
pvectChannelIdx->SetPhysicalType( ID_PHYS_TYPE_UNS_INTEGER4 );
pvectChannelIdx->SetCount( countTriggers );
for( idxTrigger = 0; idxTrigger < countTriggers; idxTrigger++ )
{
valuePQDIF.uint4 = aidxChannelTrigger[ idxTrigger ];
pvectChannelIdx->SetValue( idxTrigger, valuePQDIF );
}
pcollMain->Add( pvectChannelIdx );
}
}
// Insert an empty collection ...
pcollInstances = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
pcollInstances->SetTag( tagChannelInstances );
pcollMain->Add( pcollInstances );
// Hand it over to the record object
prec->SetMainCollection( pcollMain );
// Add the record
InsertRecord( prec, indexInsert );
}
}
return idxNewRecord;
}

View File

@@ -0,0 +1,98 @@
class CPQDIFRecord;
typedef enum
{
pqpc_Empty, // Newly created
pqpc_MatchesFile, // Contents of memory same as disk
pqpc_Modified // Contents of memory have been modified
} PQPC_Status;
class CPQDIF_PersistController
{
public:
CPQDIF_PersistController();
virtual ~CPQDIF_PersistController();
// Public member functions
public:
virtual long GetRecordCount( void ) const;
virtual CPQDIFRecord * GetRecord( long index );
virtual CPQDIFRecord * GetRecordFull( long index ) = 0;
virtual bool InsertRecord( CPQDIFRecord * prec, long indexToInsert );
virtual bool RemoveRecord( long index );
// Other public member functions
public:
virtual long CreateContainerRecord
(
const char * language,
const char * title,
const char * subject,
const char * author,
const char * keywords,
const char * comments,
const char * lastSavedBy,
const char * application,
const char * security,
const char * owner,
const char * copyright,
const char * trademarks,
const char * notes
);
virtual long CreateContainerRecord
(
const char * szFileName,
const TIMESTAMPPQDIF * timeCreate,
const long lMajor,
const long lMinor,
const long lCompatMajor,
const long lCompatMinor
);
long CreateDataSourceRecord
(
long indexInsert,
const GUID& idDataSourceType,
const GUID& idVendor,
const GUID& idEquipment,
const char * serialNumberDS, // Optional (can be NULL)
const char * versionDS, // Optional
const char * nameDS,
const char * ownerDS, // Optional
const char * locationDS, // Optional
const char * timeZoneDS // Optional
);
long CreateMonitorSettingsRecord
(
long indexInsert
);
long CreateMonitorSettingsRecord
(
long indexInsert,
const TIMESTAMPPQDIF * timeEffective,
const TIMESTAMPPQDIF * timeInstalled,
const TIMESTAMPPQDIF * timeRemoved,
bool useCal,
bool useTrans
);
long CreateObservationRecord
(
long indexInsert,
const char * name,
const TIMESTAMPPQDIF * timeCreate,
const TIMESTAMPPQDIF * timeStart,
UINT4 idTriggerMethod,
const TIMESTAMPPQDIF * timeTriggered, // Optional (can be NULL)
long countTriggers,
UINT4 * aidxChannelTrigger // Array of channel indices[ countTriggers ]
// Optional (can be NULL)
);
// Member data
protected:
CPQPtrArray m_arrayRecords;
PQPC_Status m_state;
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,68 @@
class CPQDIF_StreamIO;
class CPQDIF_StreamProcessor;
enum PF_StreamIO;
class CPQDIF_PC_FlatFile : public CPQDIF_PersistController
{
public:
CPQDIF_PC_FlatFile();
~CPQDIF_PC_FlatFile();
// Overridables
public:
virtual CPQDIFRecord * GetRecordFull( long index );
// Public interface
public:
void SetFileName( const char * fname )
{ m_fname = fname; }
const char * GetFileName( void )
{ return m_fname.c_str(); }
void SetChunkInput( BYTE * chunk, long size );
bool GetChunkOutputSize( long& size );
bool GetChunkOutput( BYTE * chunk, long size );
bool GetCanWriteIncremental( void )
{
UpdateInformation(); // need to fix
return false;
//return m_pstream->CanWriteIncremental();
}
int ReadHeaders( void );
bool ImportContainerAndRecordsFromChunk( BYTE * chunk, long size, bool &bCompressed );
bool ImportRecordsFromChunk( BYTE * chunk, long size, bool bCompressed );
bool WriteIncremental( void );
bool WriteNew( void );
bool WriteRecordsToFile( void );
long GetCompressionAlgorithm();
void SetCompressionAlgorithm( long algNew );
long GetCompressionStyle();
void SetCompressionStyle( long styleNew );
// Implementation
protected:
void UpdateInformation( void );
// Member data
private:
// Chunk (if NULL, assume physical file)
BYTE * m_chunk;
long m_sizeChunk;
// Physical flat file path
string m_fname;
// Keep track of which stream type
enum PF_StreamIO m_whichStream;
CPQDIF_StreamIO * m_pstream;
CPQDIF_StreamProcessor * m_pprocHeader;
CPQDIF_StreamProcessor * m_pprocBody;
};

View File

@@ -0,0 +1,89 @@
// File name: $Workfile: pqbytearray.cpp $
// Last modified: $Modtime: 9/21/00 8:51a $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/pqbytearray.cpp $
// VCS revision: $Revision: 7 $
#include "PQDIF_classes.h"
CPQByteArray::CPQByteArray()
{
m_data = NULL;
m_size = 0;
m_max = 0;
m_growBy = 64;
}
CPQByteArray::~CPQByteArray()
{
if( m_data )
{
free( m_data );
}
}
bool CPQByteArray::SetSize( int NewSize, int GrowBy )
{
if( GrowBy > 0 )
m_growBy = GrowBy;
// Grow?
if( NewSize > m_max )
{
int max = (( NewSize/m_growBy ) + 1)*m_growBy;
BYTE * data = (BYTE *) realloc( (void *) m_data, max );
if( data != NULL || max == 0 )
{
m_data = data;
m_size = NewSize;
m_max = max;
}
}
else
{
m_size = NewSize;
}
return ( m_size == NewSize );
}
int CPQByteArray::Add( BYTE value )
{
int pos = m_size;
if( SetSize( m_size + 1 ) )
{
m_data[ pos ] = value;
return pos;
}
else
{
return -1;
}
}
int CPQByteArray::Append( BYTE * values, int count )
{
int pos = m_size;
if( SetSize( m_size + count, m_growBy ) )
{
memcpy( m_data + pos, values, count );
return pos;
}
else
{
return -1;
}
}

View File

@@ -0,0 +1,59 @@
// File name: $Workfile: pqbytearray.h $
// Last modified: $Modtime: 9/20/00 4:19p $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/pqbytearray.h $
// VCS revision: $Revision: 4 $
class CPQByteArray
{
public:
CPQByteArray();
~CPQByteArray();
public:
inline int GetSize( void ) const
{
return m_size;
}
bool SetSize( int NewSize, int GrowBy = -1 );
inline BYTE GetAt( int idx ) const
{
//ASSERT( m_data != NULL && idx >= 0 && idx < m_size );
return m_data[ idx ];
}
inline void SetAt( int idx, BYTE value )
{
//ASSERT( m_data != NULL && idx >= 0 && idx < m_size );
m_data[ idx ] = value;
}
BYTE& ElementAt( int idx ) const
{
//ASSERT( m_data != NULL && idx >= 0 && idx < m_size );
return m_data[ idx ];
}
inline const BYTE * GetData( void ) const { return m_data; }
inline BYTE * GetData( void ) { return m_data; }
int Add( BYTE value );
int Append( BYTE * values, int count );
BYTE operator[] ( int idx ) const
{
//ASSERT( m_data != NULL && idx >= 0 && idx < m_size );
return m_data[ idx ];
}
BYTE& operator[] ( int idx )
{
//ASSERT( m_data != NULL && idx >= 0 && idx < m_size );
return m_data[ idx ];
}
protected:
BYTE * m_data;
int m_size;
int m_max;
int m_growBy;
};

View File

@@ -0,0 +1,262 @@
/*
** CPQDIF_Factory class. Implements two sets of member functions:
** - The "abstract factory" methods such as NewPersistController() are
** used to create objects in such a way that the caller does not need to
** know the exact "concrete" class.
**
** --------------------------------------------------------------------------
** This class is a Singleton class; this means that only one instance of it
** should ever be created. This instance is made global, and is one of the
** only global objects in the entire system.
** --------------------------------------------------------------------------
**
** File name: $Workfile: pqdfacty.cpp $
** Last modified: $Modtime: 3/21/99 10:11p $
** Last modified by: $Author: Erich $
**
** VCS archive path: $Archive: /Hank/Tools/INEx/pqdiflib/pqdfacty.cpp $
** VCS revision: $Revision: 11 $
*/
#include "PQDIF_classes.h"
// The one and only factory object (Singleton)
CPQDIF_Factory theFactory;
// Construction
// ============
CPQDIF_Factory::CPQDIF_Factory()
{
}
CPQDIF_Factory::~CPQDIF_Factory()
{
}
#ifndef _PQDIF_NO_PERSIST_CONTROLLER
// Creates a new persistence contoller of the specified concrete class.
//
CPQDIF_PersistController * CPQDIF_Factory::NewPersistController( PF_PersistController which )
{
CPQDIF_PersistController * ppc = NULL;
switch( which )
{
case PFPC_FlatFile:
ppc = new CPQDIF_PC_FlatFile();
break;
default:
// Cannot support...
ppc = NULL;
break;
}
return ppc;
}
#endif
// Creates a new stream object of the specified concrete class.
//
CPQDIF_StreamIO * CPQDIF_Factory::NewStreamIO( PF_StreamIO which )
{
CPQDIF_StreamIO * pstream = NULL;
switch( which )
{
case PSIO_FlatFile:
pstream = new CPQDIF_S_FlatFile();
break;
case PSIO_Chunk:
pstream = new CPQDIF_S_Chunk();
break;
#ifdef _PQDIF_HANK_PQDIF_STUFF
case PSIO_HCOM:
pstream = new CPQDIF_S_HCOM();
break;
#endif
default:
// Cannot support...
pstream = NULL;
break;
}
return pstream;
}
// Creates a new stream processor object. The list of concrete classes
// is extensible.
//
CPQDIF_StreamProcessor * CPQDIF_Factory::NewStreamProcessor( long which )
{
CPQDIF_StreamProcessor * pproc = NULL;
switch( which )
{
case ID_COMP_ALG_NONE:
pproc = new CPQDIF_SP_Nothing();
break;
case ID_COMP_ALG_ZLIB:
pproc = new CPQDIF_SP_ZLIB();
break;
case ID_COMP_ALG_PKZIPCL:
// No longer supported
//pproc = new CPQDIF_SP_PKZIP();
break;
default:
// Cannot support...
pproc = NULL;
break;
}
return pproc;
}
// Creates a new PQDIF record object of the specified concrete class.
//
CPQDIFRecord * CPQDIF_Factory::NewRecord( PF_Record which )
{
CPQDIFRecord * prec = NULL;
switch( which )
{
// In all cases, create a general record, but with different header tags.
case PFR_Record:
prec = new CPQDIF_R_General();
prec->HeaderSetTag( tagBlank );
break;
case PFR_Container:
prec = new CPQDIF_R_General();
prec->HeaderSetTag( tagContainer );
break;
case PFR_DataSource:
prec = new CPQDIF_R_General();
prec->HeaderSetTag( tagRecDataSource );
break;
case PFR_MonitorSettings:
prec = new CPQDIF_R_General();
prec->HeaderSetTag( tagRecMonitorSettings );
break;
case PFR_Observation:
prec = new CPQDIF_R_General();
prec->HeaderSetTag( tagRecObservation );
break;
default:
prec = NULL;
break;
}
return prec;
}
CPQDIF_R_Observation * CPQDIF_Factory::NewObservationWrapper
(
CPQDIFRecord * precBase,
CPQDIFRecord * precDataSource
)
{
CPQDIF_R_Observation * pobs = NULL;
CPQDIF_R_DataSource * pds = NULL;
pobs = new CPQDIF_R_Observation( *precBase );
if( pobs )
{
//
//
// Replaced dynamic cast with static cast. I don't understand why
// dynamic does not work (RTTI is enabled). Rob has a comment in another
// code module in the Hank data manager code that says a static cast has to
// be used in this situation since the classes involved have no data members.
//
// pds = dynamic_cast<CPQDIF_R_DataSource *>( precDataSource );
pds = static_cast<CPQDIF_R_DataSource *>( precDataSource );
if( pds )
{
pobs->SetDataSource( pds );
}
}
return pobs;
}
CPQDIF_R_Observation * CPQDIF_Factory::NewObservationWrapper2
(
CPQDIFRecord * precBase,
CPQDIFRecord * precDataSource,
CPQDIFRecord * precSettings
)
{
CPQDIF_R_Observation * pobs = NULL;
CPQDIF_R_DataSource * pds;
CPQDIF_R_Settings * psett;
pobs = new CPQDIF_R_Observation( *precBase );
if( pobs )
{
// Check the casts first
//
//
// Replaced dynamic cast with static cast. I don't understand why
// dynamic does not work (RTTI is enabled). Rob has a comment in another
// code module in the Hank data manager code that says a static cast has to
// be used in this situation since the classes involved have no data members.
//
pds = static_cast<CPQDIF_R_DataSource *>( precDataSource );
// pds = dynamic_cast<CPQDIF_R_DataSource *>( precDataSource );
if( pds )
pobs->SetDataSource( pds );
// psett = dynamic_cast<CPQDIF_R_Settings *>( precSettings );
psett = static_cast<CPQDIF_R_Settings *>( precSettings );
if( psett )
pobs->SetMonitorSettings( psett );
}
return pobs;
}
// Creates a new PQDIF element object from the specified concrete
// class.
//
CPQDIF_Element * CPQDIF_Factory::NewElement( long which )
{
CPQDIF_Element * pel = NULL;
switch( which )
{
case ID_ELEMENT_TYPE_COLLECTION:
pel = new CPQDIF_E_Collection();
break;
case ID_ELEMENT_TYPE_SCALAR:
pel = new CPQDIF_E_Scalar();
break;
case ID_ELEMENT_TYPE_VECTOR:
pel = new CPQDIF_E_Vector();
break;
default:
pel = NULL;
break;
}
return pel;
}

View File

@@ -0,0 +1,79 @@
// File name: $Workfile: pqdfacty.h $
// Last modified: $Modtime: 2/09/98 4:18p $
// Last modified by: $Author: Rob $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/pqdfacty.h $
// VCS revision: $Revision: 5 $
#include "pqdif_lg.h"
// Interface declarations
class CPQDIF_StreamIO;
class CPQDIF_StreamProcessor;
class CPQDIF_Element;
class IPQDIF_Importer;
// Parameters
enum PF_PersistController
{
PFPC_FlatFile,
PFPC_HCOM // Hank DMM (550x) implementation
};
enum PF_StreamIO
{
PSIO_FlatFile,
PSIO_Chunk,
PSIO_HCOM // Hank DMM (550x) implementation
};
enum PF_Record
{
PFR_Record,
PFR_Container,
PFR_DataSource,
PFR_MonitorSettings,
PFR_Observation
};
class CPQDIF_Factory
{
public:
CPQDIF_Factory();
~CPQDIF_Factory();
// Attributes
public:
// Operations
public:
#ifndef _PQDIF_NO_PERSIST_CONTROLLER
CPQDIF_PersistController * NewPersistController( PF_PersistController which );
#endif
CPQDIF_StreamIO * NewStreamIO( PF_StreamIO which );
CPQDIF_StreamProcessor * NewStreamProcessor( long which );
CPQDIF_Element * NewElement( long which );
CPQDIFRecord * NewRecord( PF_Record which );
CPQDIF_R_Observation * NewObservationWrapper
(
CPQDIFRecord * precBase,
CPQDIFRecord * precDataSource
);
CPQDIF_R_Observation * NewObservationWrapper2
(
CPQDIFRecord * precBase,
CPQDIFRecord * precDataSource,
CPQDIFRecord * precSettings
);
// Implementation
protected:
};
// The one and only factory object (Singleton)
extern CPQDIF_Factory theFactory;

View File

@@ -0,0 +1,31 @@
//
// This file is included just after the windows.h and STL library includes
// using namespace std; declaration and just before the standard PQDIF headers
// in PQDIF_classes.h
//
// Use this file to add custom headers for your implementation of PQDIF
//
// =============================================================================
//
// Begin Custom Header
//
// =============================================================================
//
#ifdef __BORLANDC__
#define _stricmp stricmp
#else
#if _MSC_VER >= 1100
#include <crtdbg.h>
#endif
#include <comdef.h>
#include <atlconv.h>
#endif
#undef ASSERT
#define ASSERT(x)
#undef ASSERT_VALID
#define ASSERT_VALID(x)
#undef _T
#define _T

View File

@@ -0,0 +1,13 @@
//
// This file is included after all standard PQDIF header includes in PQDIF_classes.h
//
// Use this file to add custom headers for your implementation of PQDIF
//
// =============================================================================
//
// Begin Custom Header
//
// =============================================================================
//
#include "pqdsupport.h" // COM (VARIANT) support class

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,466 @@
/*
** PQDIF - Power Quality Data Interchange Format
** Version 1.5
**
** File name: $Workfile: pqdif_ph.h $
** Last modified: $Modtime: 1/07/02 3:59p $
** Last modified by: $Author: Erich $
**
** VCS archive path: $Archive: /PQDIF/Document/IEEE/pqdif_ph.h $
** VCS revision: $Revision: 22 $
**
** PHYSICAL FORMAT DEFINITIONS
** ======================================================================
** This file contains the complete definitions for the physical
** format of a PQDIF file. It contains no information about the
** _logical_ structure, which is defined in PQDIF_LG.H
**
** ======================================================================
** The current version of this file and related information
** can be found at URL:
**
** http://grouper.ieee.org/groups/1159/3/docs.html
**
** ======================================================================
*/
#ifndef PQDIF_PH_H
#define PQDIF_PH_H
// The structures must be 1-byte packed.
//#ifdef __BORLANDC__
// #pragma pack( 1 )
//#elif _MSC_VER
// #pragma pack( push, 1 )
//#else
// #pragma pack( 1 )
//#endif
#pragma pack( 1 )
/*
** PHYSICAL TYPE IDs AND DEFINITIONS
** ======================================================================
** The physical types are intended to be fully portable.
** ======================================================================
*/
/*
** Physical representation IDs
**
** NOTE: Larger objects such as strings and BLOBs (Binary Large OBject)
** are represented as vectors of other primitive types.
**
** Examples
** --------
** ASCII string Vector of ID_PHYS_TYPE_CHAR1, NULL-terminated
** (i.e., the last character must be a NULL, to
** correspond to a C-style string).
**
** Unicode string Vector of ID_PHYS_TYPE_CHAR2.
**
** BLOB vector of ID_PHYS_TYPE_INTEGER1 or
** ID_PHYS_TYPE_UNS_INTEGER1.
*/
#define ID_PHYS_TYPE_BOOLEAN1 1
#define ID_PHYS_TYPE_BOOLEAN2 2
#define ID_PHYS_TYPE_BOOLEAN4 3
#define ID_PHYS_TYPE_CHAR1 10 // ASCII
#define ID_PHYS_TYPE_CHAR2 11 // Unicode
// Signed integers
#define ID_PHYS_TYPE_INTEGER1 20
#define ID_PHYS_TYPE_INTEGER2 21
#define ID_PHYS_TYPE_INTEGER4 22
// Unsigned integers
#define ID_PHYS_TYPE_UNS_INTEGER1 30
#define ID_PHYS_TYPE_UNS_INTEGER2 31
#define ID_PHYS_TYPE_UNS_INTEGER4 32
// Real/complex
#define ID_PHYS_TYPE_REAL4 40
#define ID_PHYS_TYPE_REAL8 41
#define ID_PHYS_TYPE_COMPLEX8 42 // Two REAL4s: real, imag
#define ID_PHYS_TYPE_COMPLEX16 43 // Two REAL8s: real, imag
// Date/time variations
#define ID_PHYS_TYPE_TIMESTAMPPQDIF 50 // Physical: TIMESTAMPPQDIF (total 12 bytes)
// GUID
#define ID_PHYS_TYPE_GUID 60 // Physical: GUID (total 16 bytes)
//WW 20240520 start
typedef unsigned int DWORD;
typedef int BOOL;
typedef unsigned char BYTE;
typedef unsigned short WORD;
typedef float FLOAT;
typedef FLOAT *PFLOAT;
typedef int INT;
typedef unsigned int UINT;
typedef unsigned int *PUINT;
/** FALSE */
#ifndef FALSE
#define FALSE 0
#endif
/** TRUE */
#ifndef TRUE
#define TRUE (!FALSE)
#endif
#if (!defined(_T)) && (!defined(__T))
#ifdef STDTIME_UNICODE
#define __T(x) L##x
#define _T(x) __T(x)
#else
#define __T(x) x
#define _T(x) x
#endif
#endif /* not defined _T and __T */
#ifdef _UNICODE
#define TCHAR wchar_t
#else
#define TCHAR char
#endif
#ifndef strcmpi
#define strcmpi strcasecmp
#endif
//WW 20240520 end
/*
** Portable primitive type definitions
*/
typedef char BOOL1;
typedef short BOOL2;
typedef int BOOL4;
typedef char CHAR1; // ASCII string character
typedef short CHAR2; // Unicode string character
typedef char INT1;
typedef short INT2;
typedef int INT4;
typedef unsigned char UINT1;
typedef unsigned short UINT2;
typedef unsigned int UINT4;
typedef float REAL4;
typedef double REAL8;
typedef struct _complex8
{
REAL4 real;
REAL4 image;
} COMPLEX8;
typedef struct _complex16
{
REAL8 real;
REAL8 image;
} COMPLEX16;
/*
** Types used in structures (but not used as primitives for elements)
*/
typedef int LINKABS4;
typedef int LINKREL4;
typedef int SIZE4;
/*
** Portable physical time structure definition
**
** (Modified version of time tracking used by Excel
** Excel counts days since 1900, converts to a double
** and adds to this a number less than 1.0 that
** is the fractional day. This structure enhances
** accuracy of this method by separating out the
** days since 1900 and seconds since midnight.)
*/
typedef struct ts
{
UINT4 day; // days since January 1, 1900 UCT
// 0xFFFFFFFF -> 4294967295 days -> a long time
REAL8 sec; // fractional seconds since midnight of day
} TIMESTAMPPQDIF;
/*
** GUID (Globally Unique IDentifier) definition
** (Used for tagging sections to identify them logically)
**
** The Unique Universal Identifier (UUID) is also known
** as a Globally Unique Identifier (GUID). It is
** a randomly generated number that due to its size,
** is guaranteed to be unique in the universe. This
** guarantees that the tags will be unique and anyone
** can generate "private" tags which will never conflict
** with the standard tags.
**
** GUID tags are used to mark the header of each record,
** as well as identify the elements in the internal structures.
*/
#ifndef GUID_DEFINED
#define GUID_DEFINED
typedef struct _GUID
{
unsigned int Data1;//WW 20240522 64λ long<6E><67>8<EFBFBD><38><EFBFBD>ֽ<EFBFBD>
unsigned short Data2;
unsigned short Data3;
unsigned char Data4[8];
} GUID;
#endif /* GUID_DEFINED */
/*
** PHYSICAL TYPE HELPER INFORMATION
** ======================================================================
** Time structure helpers
**
** The following constant is the number of days between
** 1/1/1900 and 1/1/1970. This is used to convert between
** "C Time" and Excel style day counts
** "C Time" is a 4 byte integer representing the number of
** seconds elapsed since January 1, 1970.
** Excel time is an 8 byte real number that represents
** the number of days elapsed since 1/1/1900. The fractional
** part is therefore convertable to seconds since midnight.
*/
#define EXCEL_DAYCOUNT_ADJUST 25569L
#define SECONDS_PER_DAY 86400L
/*
** Define GUID helpers
*/
#define PQDIF_IsEqualGUID(rguid1, rguid2) (!memcmp(&rguid1, &rguid2, sizeof(GUID)))
#define PQDIF_DEFINE_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \
const GUID name = { l, w1, w2, { b1, b2, b3, b4, b5, b6, b7, b8 } }
#define PQDIFGUID_IsEqual(rguid1, rguid2) ( rguid1.Data1==rguid2.Data1 && rguid1.Data2==rguid2.Data2 && rguid1.Data3==rguid2.Data3 \
&& rguid1.Data4[0]==rguid2.Data4[0] && rguid1.Data4[1]==rguid2.Data4[1] \
&& rguid1.Data4[2]==rguid2.Data4[2] && rguid1.Data4[3]==rguid2.Data4[3] \
&& rguid1.Data4[4]==rguid2.Data4[4] && rguid1.Data4[5]==rguid2.Data4[5] \
&& rguid1.Data4[6]==rguid2.Data4[6] && rguid1.Data4[7]==rguid2.Data4[7] )
/*
** HIGH-LEVEL FILE STRUCTURE
** ======================================================================
** The top-level structure is a series of independent records with
** header and body sections.
**
** ======================================================================
** Fundamental premise for file format writing: File must be capable of
** being written to incrementally. For this reason, the basic structure
** is a series of independent records. Additional records can be appended
** to the file at any time.
**
** ======================================================================
** The top-level structure is a series of independent records with
** header and body sections:
**
** +--------------------------------+
** | Record 0 Header |
** /---+--------------------------------+
** | | Record 0 Body |
** | +--------------------------------+
** \-->+--------------------------------+
** | Record 1 Header |
** /---+--------------------------------+
** | | Record 1 Body |
** | +--------------------------------+
** ... ...
** \-->+--------------------------------+
** | Record n Header |
** +--------------------------------+
** | Record n Body |
** +--------------------------------+
**
** ======================================================================
** Note that each record header has a LINKABS4 -- an absolute offset in
** the file -- to the next record. This allows new records to be inserted
** in the middle of the file, and obsolete records to be deleted.
**
** ======================================================================
** All references which are defined by the type LINKREL4 are offsets
** within the record body itself -- they are not absolute offsets to the
** entire file. Thus, each record body is independent of the others. Only
** the record header need be modified if a record is moved, deleted, or
** inserted.
**
** ======================================================================
*/
/*
** Record header
**
** The header contains a GUID signature (for testing corruptness),
** header size, the size of the record that follows, record tag, and
** fill bytes to make the header 64 bytes in length
*/
struct c_record_mainheader
{
GUID guidRecordSignature; // Signature to verify a valid header
GUID tagRecordType; // Tag to identify the record type
// (This also identifies the first
// collection in the record.)
SIZE4 sizeHeader; // Size of this header in bytes
SIZE4 sizeData; // Size of the body in bytes (record data
// that follows header)
LINKABS4 linkNextRecord; // Offset to the next record -- absolute
// reference within the file. If 0, this
// is the last record in the file.
UINT4 checksum; // Optional checksum (such as a 32-bit CRC)
// of the record body to verify decompression.
UINT4 auiReserved[ 4 ]; // Reserved to fill structure to 64 bytes
// -- should be filled with 0
};
/*
** RECORD BODY STRUCTURE
** ======================================================================
** The record body always begins with a Collection element. This is
** defined below in the record structure.
**
** ======================================================================
** The fundamental premise for the standard structures is to
** assure 4 byte alignment. All of the structures conform to this
** premise. In addition, the data values associated with scalars and
** vectors must be padded out to 4-byte multiples. This _total_ size
** will be specified in the c_collection_element structure (sizeElement).
**
** ======================================================================
** The three main elements are:
**
** 1. Collection Holds an array of pointers to other elements
** (it could contain another collection)
** 2. Scalar Holds a single data value (of a physical type)
** 3. Vector Holds an array of data values (of a physical type)
** ======================================================================
*/
#define ID_ELEMENT_TYPE_COLLECTION 1
#define ID_ELEMENT_TYPE_SCALAR 2
#define ID_ELEMENT_TYPE_VECTOR 3
/*
** The collection element
**
** ... is made by combining a c_collection with an array of
** c_collection_element, which provide pointers to the
** other elements in the collection.
*/
struct c_collection
{
SIZE4 count; // The number of elements in this
// collection.
// c_collection_element ceElements[]; // Array [count] of the elements
// in the collection.
};
struct c_collection_element
{
GUID tagElement; // Identifier for this element in the collection.
// (4) 1-byte members keep the structure 4-byte aligned.
INT1 typeElement; // Type of element (ID_ELEMENT_TYPE_COLLECTION,
// _SCALAR or _VECTOR).
INT1 typePhysical; // Physical type of the value which follows
// (ID_PHYS_TYPE_INTEGER1, etc.). This is unused
// if the element is a collection and should be
// set to 0.
BOOL1 isEmbedded; // FALSE (0) - use the link to find the next element
// TRUE (1) - the scalar data value is embedded
// (may not be used with vectors)
INT1 reserved; // Fill with 0
// The following 8 bytes can point to another location in the record
// or it can hold the actual data value (if it fits in 8 bytes).
// This allows small scalars to be stored with much less space overhead.
union
{
// isEmbedded What to use
// ---------- -------------------------------------------------
// FALSE Use link to find the next element (and its size).
// TRUE Use valueEmbedded to find the data directly.
struct
{
LINKREL4 linkElement; // Offset to the element -- this offset
// is relative within the record body.
SIZE4 sizeElement; // Specifies actual size of the element
// -- should be padded to even
// multiples of 4 bytes
} link;
UINT1 valueEmbedded[ 8 ]; // The scalar data value
// (less than or equal to 8 bytes)
};
};
/*
** The scalar element
**
** This structure has no members, but is included
** for completeness.
**
** struct c_scalar
** {
** // (type) value; // A single value follows of variable length,
** // depending on the physical type.
** };
*/
/*
** The vector element
*/
struct c_vector
{
SIZE4 count;
// (type) values[]; // An array of values [count] follows of
// variable length, depending on the
// physical type.
};
/*
** NOTE
** ======================================================================
** For more detailed information about how to use these physical
** structures to create a PQDIF file, see the logical structure header
** file -- PQDIF_LG.H
*/
// Return to previous packing value
//#ifdef __BORLANDC__
// #include <poppack.h>
//#elif _MSC_VER
// #pragma pack( pop )
//#else
// #pragma pack()
//#endif
#pragma pack( )
#endif // PQDIF_PH_H

View File

@@ -0,0 +1,945 @@
# Microsoft Developer Studio Generated Dependency File, included by pqdiflib.mak
.\el_base.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\el_coll.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\el_scal.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\el_vect.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\pcn_base.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\pcn_flat.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\pqbytearray.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\pqdfacty.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\pqdinfo.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\name_id.inc"\
".\name_tag.inc"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\pqdsupport.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\pqptrarray.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\proc_bas.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
".\zconf.h"\
".\zlib.h"\
.\proc_not.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
".\zconf.h"\
".\zlib.h"\
.\proc_zlib.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
".\zconf.h"\
".\zlib.h"\
.\rec_base.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\rec_container.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\rec_datasource.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\rec_general.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\rec_observ.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\rec_settings.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\ser_alloc.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\ser_cont_el.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\ser_iter_el.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\str_base.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\str_chnk.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\
.\str_flat.cpp : \
"..\..\..\..\..\program files\microsoft visual studio\vc98\include\basetsd.h"\
".\el_base.h"\
".\el_coll.h"\
".\el_scal.h"\
".\el_vect.h"\
".\pcn_base.h"\
".\pcn_flat.h"\
".\pqbytearray.h"\
".\pqdfacty.h"\
".\PQDIF_classes.h"\
".\pqdif_custom_1.h"\
".\pqdif_custom_2.h"\
".\pqdif_id.h"\
".\pqdif_lg.h"\
".\pqdif_ph.h"\
".\pqdinfo.h"\
".\pqdsupport.h"\
".\pqptrarray.h"\
".\proc_bas.h"\
".\proc_not.h"\
".\proc_zlib.h"\
".\rec_base.h"\
".\rec_container.h"\
".\rec_datasource.h"\
".\rec_general.h"\
".\rec_observ.h"\
".\rec_settings.h"\
".\ser_alloc.h"\
".\ser_cont_el.h"\
".\ser_iter_el.h"\
".\str_base.h"\
".\str_chnk.h"\
".\str_flat.h"\

View File

@@ -0,0 +1,832 @@
/*
** CPQDIF_Info class. Implements informational member functions so that
** certain types of information can be encapsulated here. This allows us
** to concentrate knowledge at one point so it can be more easily managed.
** --------------------------------------------------------------------------
** This class is a Singleton class; this means that only one instance of it
** should ever be created. This instance is made global, and is one of the
** only global objects in the entire system.
** --------------------------------------------------------------------------
**
** File name: $Workfile: pqdinfo.cpp $
** Last modified: $Modtime: 6/19/02 3:51p $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/pqdinfo.cpp $
** VCS revision: $Revision: 17 $
*/
#include "PQDIF_classes.h"
// The one and only information object (Singleton)
// ===================================
CPQDIF_Info theInfo;
// String for unrecognized tags and IDs.
static const char * szUnrecognized = "< Unrecognized >";
static const char * szEmpty = "";
// Sorting predicated for Name Info classes
class CLess_NI_Tag // : public less<NI_Tag>
{
public:
inline bool operator()(const NI_Tag &x, const NI_Tag &y) const
{
return ( memcmp( &x.m_tag, &y.m_tag, sizeof( GUID ) ) < 0 );
}
};
class CLess_NI_ID_GUID // : public less<NI_ID_GUID>
{
public:
inline bool operator()(const NI_ID_GUID &x, const NI_ID_GUID &y) const
{
return ( memcmp( &x.m_id, &y.m_id, sizeof( GUID ) ) < 0 );
}
};
class CLess_NI_ID_Int // : public less<NI_ID_Int>
{
public:
bool operator()(const NI_ID_Int &x, const NI_ID_Int &y) const
{
int iResult = memcmp( &x.m_tag, &y.m_tag, sizeof( GUID ) );
if( iResult == 0 )
{
if( x.m_id < y.m_id )
iResult = -1;
}
return iResult < 0;
}
};
// Local macros for adding entries
// -------------------------------
#ifdef _PQDIF_ALIAS_TAG
#define ADD_TAG_ENTRY( _tag ) \
extern const char _PQDIF_ALIAS_##_tag[]; \
nameTag.m_tag = _tag; \
nameTag.m_name = #_tag; \
nameTag.m_alias = _PQDIF_ALIAS_##_tag; \
m_listTags.push_back( nameTag );
#else
#define ADD_TAG_ENTRY( _tag ) \
nameTag.m_tag = _tag; \
nameTag.m_name = #_tag; \
m_listTags.push_back( nameTag );
#endif
#ifdef _PQDIF_ALIAS_ID
#define ADD_ID_GUID_ENTRY( _id, _tag ) \
extern const char _PQDIF_ALIAS_##_id[]; \
nameGuid.m_id = _id; \
nameGuid.m_tag = _tag; \
nameGuid.m_name = #_id; \
nameGuid.m_alias = _PQDIF_ALIAS_##_id; \
m_listGUIDs.push_back( nameGuid );
#define ADD_ID_UINT4_ENTRY( _id, _tag )\
extern const char _PQDIF_ALIAS_##_id[]; \
nameInt.m_id = _id; \
nameInt.m_tag = _tag; \
nameInt.m_name = #_id; \
nameInt.m_alias = _PQDIF_ALIAS_##_id; \
m_listInts.push_back( nameInt );
#else
#define ADD_ID_GUID_ENTRY( _id, _tag ) \
nameGuid.m_id = _id; \
nameGuid.m_tag = _tag; \
nameGuid.m_name = #_id; \
m_listGUIDs.push_back( nameGuid );
#define ADD_ID_UINT4_ENTRY( _id, _tag )\
nameInt.m_id = _id; \
nameInt.m_tag = _tag; \
nameInt.m_name = #_id; \
m_listInts.push_back( nameInt );
#endif
#define ADD_TYPE_ENTRY( _type )\
nameType.m_type = _type; \
nameType.m_name = #_type; \
m_listTypes.push_back( nameType );
// Construction
// ============
BYTE CPQDIF_Info::m_sizeDataTable[] =
{
1, 1, 2, 4, 1, 1, 1, 1, 1, 1,
1, 2, 1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 4, 1, 1, 1, 1, 1, 1, 1,
1, 2, 4, 1, 1, 1, 1, 1, 1, 1,
4, 8, 8, 16, 1, 1, 1, 1, 1, 1,
12, 1, 1, 1, 1, 1, 1, 1, 1, 1,
16, 1, 1, 1, 1, 1, 1, 1, 1, 1,
};
CPQDIF_Info::CPQDIF_Info()
{
NI_Tag nameTag;
NI_ID_GUID nameGuid;
NI_ID_Int nameInt;
NI_Type nameType;
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_BOOLEAN1 ) == sizeof( BOOL1 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_BOOLEAN2 ) == sizeof( BOOL2 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_BOOLEAN4 ) == sizeof( BOOL4 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_CHAR1 ) == sizeof( CHAR1 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_CHAR2 ) == sizeof( CHAR2 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_INTEGER1 ) == sizeof( INT1 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_INTEGER2 ) == sizeof( INT2 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_INTEGER4 ) == sizeof( INT4 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_UNS_INTEGER1 ) == sizeof( UINT1 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_UNS_INTEGER2 ) == sizeof( UINT2 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_UNS_INTEGER4 ) == sizeof( UINT4 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_REAL4 ) == sizeof( REAL4 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_REAL8 ) == sizeof( REAL8 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_COMPLEX8 ) == sizeof( COMPLEX8 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_COMPLEX16 ) == sizeof( COMPLEX16 ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_TIMESTAMPPQDIF ) == sizeof( TIMESTAMPPQDIF ) );
//ASSERT( GetNumBytesOfType( ID_PHYS_TYPE_GUID ) == sizeof( GUID ) );
// Treat the 'blank' tag a little differently
nameTag.m_tag = tagBlank;
nameTag.m_name = "< Blank >";
m_listTags.push_back( nameTag );
// Tag names
#include "name_tag.inc"
#ifdef _PQDIF_EXTENDED_TAGS
#include "name_tag_extended.inc"
#endif
// ID names
#include "name_id.inc"
#ifdef _PQDIF_EXTENDED_TAGS
#include "name_id_extended.inc"
#endif
// Physical type names
ADD_TYPE_ENTRY( ID_PHYS_TYPE_BOOLEAN1 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_BOOLEAN2 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_BOOLEAN4 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_CHAR1 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_CHAR2 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_INTEGER1 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_INTEGER2 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_INTEGER4 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_UNS_INTEGER1 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_UNS_INTEGER2 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_UNS_INTEGER4 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_REAL4 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_REAL8 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_COMPLEX8 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_COMPLEX16 );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_TIMESTAMPPQDIF );
ADD_TYPE_ENTRY( ID_PHYS_TYPE_GUID );
// Sort the lists.
sort( m_listTags.begin(), m_listTags.end(), CLess_NI_Tag() );
sort( m_listGUIDs.begin(), m_listGUIDs.end(), CLess_NI_ID_GUID() );
sort( m_listInts.begin(), m_listInts.end(), CLess_NI_ID_Int() );
#ifdef TEST
#ifndef TRACE
#define TRACE printf
#endif
// Check out each tag.
int iCount = GetTagCount();
int iTag;
for( iTag = 0; iTag < iCount; iTag++)
{
GUID tag, tag1;
GUID guidID, guidID1;
int iID, iID1;
string s;
GetTagGUID( iTag, tag );
GetTagName( iTag, s );
//ASSERT( s == GetNameOfTag( tag ) );
//ASSERT( s == GetNameTag( tag ) );
//ASSERT( s == GetAliasTag( tag ) );
//ASSERT( GetTagFromName( s.c_str(), tag1 ) && tag == tag1 );
TRACE( "%s %s\n", GetNameTag( tag ), GetAliasTag( tag ) );
// Check out each integer value for this tag.
int iCountInt = GetIDCountInt( tag );
int iInt;
for( iInt = 0; iInt < iCountInt; iInt++ )
{
s = GetIDNameInt( tag, iInt, iID );
//ASSERT( s == GetNameOfID( tag, iID ) );
//ASSERT( s == GetNameID( tag, iID ) );
//ASSERT( GetIDFromName( s.c_str(), tag1, iID1 )
&& tag == tag1
&& iID == iID1 );
TRACE( " %s %s\n", GetNameID( tag, iID ), GetAliasID( tag, iID ) );
}
// Check out each GUID value for this tag.
int iCountGUID = GetIDCountGUID( tag );
int iGUID;
for( iGUID = 0; iGUID < iCountGUID; iGUID++ )
{
s = GetIDNameGUID( tag, iGUID, guidID );
//ASSERT( s == GetNameOfID( guidID ) );
//ASSERT( s == GetNameID( guidID ) );
//ASSERT( GetIDFromName( s.c_str(), guidID1 )
&& guidID == guidID1 );
TRACE( " %s %s\n", GetNameID( guidID ), GetAliasID( guidID ) );
}
}
#endif
return;
}
CPQDIF_Info::~CPQDIF_Info()
{
}
const char * CPQDIF_Info::GetNameOfTag( const GUID& tag )
{
const char *szName = szUnrecognized;
NI_Tag * pInfo = _FindTag( tag );
if( pInfo )
szName = pInfo->m_name;
return szName;
}
const char * CPQDIF_Info::GetNameOfID( const GUID& id )
{
const char *szName = szUnrecognized;
NI_ID_GUID * pInfo = _FindGUID( id );
if( pInfo )
szName = pInfo->m_name;
return szName;
}
const char * CPQDIF_Info::GetNameOfID( const GUID& tag, int id )
{
const char *szName = szUnrecognized;
NI_ID_Int * pInfo = _FindInt( tag, id );
if( pInfo )
szName = pInfo->m_name;
return szName;
}
const char * CPQDIF_Info::GetNameOfPhysType( INT4 type )
{
const char *szName = szUnrecognized;
NI_Type * pInfo = _FindType( type );
if( pInfo )
szName = pInfo->m_name;
return szName;
}
const char * CPQDIF_Info::GetNameTag( const GUID& tag )
{
const char *szName = NULL;
NI_Tag * pInfo = _FindTag( tag );
if( pInfo )
szName = pInfo->m_name;
return szName;
}
const char * CPQDIF_Info::GetNameID
(
const GUID& id
)
{
const char *szName = NULL;
NI_ID_GUID * pInfo = _FindGUID( id );
if( pInfo )
szName = pInfo->m_name;
return szName;
}
const char * CPQDIF_Info::GetNameID
(
const GUID& tag,
int id
)
{
const char *szName = NULL;
NI_ID_Int * pInfo = _FindInt( tag, id );
if( pInfo )
szName = pInfo->m_name;
return szName;
}
const char * CPQDIF_Info::GetNamePhysType( INT4 type )
{
const char *szName = NULL;
NI_Type * pInfo = _FindType( type );
if( pInfo )
szName = pInfo->m_name;
return szName;
}
const char * CPQDIF_Info::GetAliasTag( const GUID& tag )
{
const char *szName = szEmpty;
NI_Tag * pInfo = _FindTag( tag );
if( pInfo )
{
szName = pInfo->m_alias;
if( szName == NULL )
szName = pInfo->m_name;
}
return szName;
}
const char * CPQDIF_Info::GetAliasID( const GUID& id )
{
const char *szName = szEmpty;
NI_ID_GUID * pInfo = _FindGUID( id );
if( pInfo )
{
szName = pInfo->m_alias;
if( szName == NULL )
szName = pInfo->m_name;
}
return szName;
}
const char * CPQDIF_Info::GetAliasID( const GUID& tag, int id )
{
const char *szName = szEmpty;
NI_ID_Int * pInfo = _FindInt( tag, id );
if( pInfo )
{
szName = pInfo->m_alias;
if( szName == NULL )
szName = pInfo->m_name;
}
return szName;
}
const char * CPQDIF_Info::GetAliasPhysType( INT4 type )
{
const char *szName = szEmpty;
NI_Type * pInfo = _FindType( type );
if( pInfo )
szName = pInfo->m_alias;
return szName;
}
bool CPQDIF_Info::GetTagFromName( const char *szName, GUID& tag )
{
bool bFound = false;
CList_NI_Tag::iterator iter;
for( iter = m_listTags.begin();
iter != m_listTags.end();
++iter )
{
#ifdef WIN32
if (_strcmpi(szName, iter->m_name) == 0)
#else
if (strcmpi(szName, iter->m_name) == 0)
#endif // WIN32
{
tag = iter->m_tag;
bFound = true;
break;
}
}
return bFound;
}
bool CPQDIF_Info::GetIDFromName( const char *szName, GUID& valueID )
{
bool bFound = false;
CList_NI_ID_GUID::iterator iter;
for( iter = m_listGUIDs.begin();
iter != m_listGUIDs.end();
++iter )
{
#ifdef WIN32
if (_strcmpi(szName, iter->m_name) == 0)
#else
if (strcmpi(szName, iter->m_name) == 0)
#endif // WIN32
{
valueID = iter->m_id;
bFound = true;
break;
}
}
return bFound;
}
bool CPQDIF_Info::GetIDFromName( const char *szName, GUID& tagOwner, int &valueID )
{
bool bFound = false;
CList_NI_ID_Int::iterator iter;
for( iter = m_listInts.begin();
iter != m_listInts.end();
++iter )
{
#ifdef WIN32
if (_strcmpi(szName, iter->m_name) == 0)//WW 20240520 stricmp
#else
if (strcmpi(szName, iter->m_name) == 0)//WW 20240520 stricmp
#endif // WIN32
{
tagOwner = iter->m_tag;
valueID = iter->m_id;
bFound = true;
break;
}
}
return bFound;
}
SIZE4 CPQDIF_Info::GetNumBytesOfType( int idType )
{
SIZE4 rc = 1L;
if( idType >= 0 && idType < sizeof( m_sizeDataTable )/sizeof( m_sizeDataTable[0] ) )
{
rc = (SIZE4)m_sizeDataTable[ idType ];
}
return rc;
}
bool CPQDIF_Info::GetTagGUID( int index, GUID& guidTag )
{
bool status = false;
NI_Tag * info;
info = _LookupTag( index );
if( info )
{
guidTag = info->m_tag;
status = true;
}
return status;
}
bool CPQDIF_Info::GetTagName( int index, string& nameTag )
{
bool status = false;
NI_Tag * info;
info = _LookupTag( index );
if( info )
{
nameTag = info->m_name;
status = true;
}
return status;
}
int CPQDIF_Info::GetIDCountGUID
(
const GUID& tagOwner
)
{
CList_NI_ID_GUID::iterator iter;
int countID = 0;
for( iter = m_listGUIDs.begin();
iter != m_listGUIDs.end();
++iter )
{
// Matched class ID
if(PQDIF_IsEqualGUID(iter->m_tag , tagOwner) )
{
countID++;
}
}
return countID;
}
const char * CPQDIF_Info::GetIDNameGUID
(
const GUID& tagOwner,
int idxID,
GUID& valueID
)
{
NI_ID_GUID * info;
const char * name = NULL;
info = _LookupGUID( tagOwner, idxID );
if( info )
{
name = info->m_name;
valueID = info->m_id;
}
return name;
}
int CPQDIF_Info::GetIDCountInt
(
const GUID& tagOwner
)
{
CList_NI_ID_Int::iterator iter;
int countID = 0;
for( iter = m_listInts.begin();
iter != m_listInts.end();
++iter )
{
// Matched class ID
if(PQDIF_IsEqualGUID(iter->m_tag , tagOwner) )
{
countID++;
}
}
return countID;
}
const char * CPQDIF_Info::GetIDNameInt
(
const GUID& tagOwner,
int idxID,
int& valueID
)
{
NI_ID_Int * info;
const char * name = NULL;
info = _LookupInt( tagOwner, idxID );
if( info )
{
name = info->m_name;
valueID = info->m_id;
}
return name;
}
// Lookup functions
// ----------------
NI_Tag * CPQDIF_Info::_FindTag( const GUID &tag )
{
NI_Tag * pInfo = NULL;
NI_Tag info;
info.m_tag = tag;
CList_NI_Tag::iterator iter;
iter = lower_bound( m_listTags.begin(), m_listTags.end(),
info, CLess_NI_Tag() );
if(PQDIF_IsEqualGUID(iter->m_tag , tag) )
{
pInfo = &( *iter );
}
return pInfo;
}
NI_ID_GUID * CPQDIF_Info::_FindGUID
(
const GUID& id
)
{
NI_ID_GUID * pInfo = NULL;
NI_ID_GUID info;
info.m_id = id;
CList_NI_ID_GUID::iterator iter;
iter = lower_bound( m_listGUIDs.begin(), m_listGUIDs.end(),
info, CLess_NI_ID_GUID() );
if(PQDIF_IsEqualGUID(iter->m_id , id ))
{
pInfo = &( *iter );
}
return pInfo;
}
NI_ID_Int * CPQDIF_Info::_FindInt
(
const GUID& tag,
int id
)
{
NI_ID_Int *pInfo = NULL;
NI_ID_Int info;
info.m_tag = tag;
info.m_id = id;
CList_NI_ID_Int::iterator iter;
iter = lower_bound( m_listInts.begin(), m_listInts.end(),
info, CLess_NI_ID_Int() );
if(PQDIF_IsEqualGUID(iter->m_tag , tag)
&& PQDIF_IsEqualGUID(iter->m_id , id ))
{
pInfo = &( *iter );
}
return pInfo;
}
NI_Type * CPQDIF_Info::_FindType( INT4 type )
{
NI_Type * pInfo = NULL;
CList_NI_Type::iterator iter;
for( iter = m_listTypes.begin();
iter != m_listTypes.end();
++iter )
{
// Matched tag?
if( iter->m_type == (int) type )
{
pInfo = &( *iter );
break;
}
}
return pInfo;
}
NI_Tag * CPQDIF_Info::_LookupTag( int idxLook )
{
NI_Tag * info = NULL;
if( idxLook >= 0 && idxLook < m_listTags.size() )
{
info = &m_listTags[ idxLook ];
}
return info;
}
NI_ID_GUID * CPQDIF_Info::_LookupGUID
(
const GUID& tagOwner,
int idxLook
)
{
CList_NI_ID_GUID::iterator iter;
int idxThis;
NI_ID_GUID * info = NULL;
idxThis = 0;
for( iter = m_listGUIDs.begin();
iter != m_listGUIDs.end();
++iter )
{
if(PQDIF_IsEqualGUID(iter->m_tag , tagOwner ))
{
// Matched class ID
if( idxThis == idxLook )
{
info = &(*iter);
break;
}
idxThis++;
}
}
return info;
}
NI_ID_Int * CPQDIF_Info::_LookupInt
(
const GUID& tagOwner,
int idxLook
)
{
CList_NI_ID_Int::iterator iter;
int idxThis;
NI_ID_Int * info = NULL;
idxThis = 0;
for( iter = m_listInts.begin();
iter != m_listInts.end();
++iter )
{
// Matched owner?
if(PQDIF_IsEqualGUID(iter->m_tag , tagOwner) )
{
if( idxThis == idxLook )
{
info = &(*iter);
break;
}
idxThis++;
}
}
return info;
}

View File

@@ -0,0 +1,190 @@
// File name: $Workfile: pqdinfo.h $
// Last modified: $Modtime: 7/27/01 5:44p $
// Last modified by: $Author: Jack $
//
// VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/pqdinfo.h $
// VCS revision: $Revision: 12 $
// class CPQDIF_Info
// Base info class
// ---------------
class NameInfo
{
public:
inline NameInfo()
{
m_name = NULL;
m_alias = NULL;
}
const char * m_name; // Name of item in the list (tag, ID, etc.)
const char * m_alias; // Alias for the item
};
// Sub info classes
// ----------------
class NI_Tag : public NameInfo
{
public:
GUID m_tag;
};
class NI_ID_GUID : public NameInfo
{
public:
GUID m_tag; // Owner
GUID m_id; // ID value
};
class NI_ID_Int : public NameInfo
{
public:
GUID m_tag; // Owner
int m_id; // ID value
};
class NI_Type : public NameInfo
{
public:
int m_type; // Physical type
};
// List classes
// ------------
typedef vector<NI_Tag> CList_NI_Tag;
typedef vector<NI_ID_GUID> CList_NI_ID_GUID;
typedef vector<NI_ID_Int> CList_NI_ID_Int;
typedef vector<NI_Type> CList_NI_Type;
class CPQDIF_Info
{
public:
CPQDIF_Info();
~CPQDIF_Info();
// Attributes
public:
// Operations
public:
// Name encoding. These methods always return a
// valid string. "< Unrecognized >" is returned if
// the requested value is not found.
const char * GetNameOfTag( const GUID& tag );
const char * GetNameOfID( const GUID& valueID );
const char * GetNameOfID( const GUID& tagOwner, int valueID );
const char * GetNameOfPhysType( INT4 type );
// Same as NameOf functions execept that NULL is
// returned for undefined requests.
const char * GetNameTag( const GUID& tag );
const char * GetNameID( const GUID& valueID );
const char * GetNameID( const GUID& tagOwner, int valueID );
const char * GetNamePhysType( INT4 type );
// Alias encoding functions. "" is returned if the requested
// value is not found.
const char * GetAliasTag( const GUID& tag );
const char * GetAliasID( const GUID& valueID );
const char * GetAliasID( const GUID& tagOwner, int valueID );
const char * GetAliasPhysType( INT4 type );
// Name decoding. These methods return true if
// the requested value is found.
bool GetTagFromName( const char *szName, GUID& tag );
bool GetIDFromName( const char *szName, GUID& valueID );
bool GetIDFromName( const char *szName, GUID& tagOwner, int &valueID );
// Data manipulation
static SIZE4 GetNumBytesOfType( int typePhysical );
static inline SIZE4 padSizeTo4Bytes( SIZE4 sizeOrig )
{
return ( ( sizeOrig + 3 ) & ~3 );
}
static inline BYTE * GetPtrToDataValue( int /*typePhysical*/, PQDIFValue& value )
{
return (BYTE *)&value;
}
static inline const BYTE * GetPtrToDataValue( int /*typePhysical*/, const PQDIFValue& value )
{
return (const BYTE *)&value;
}
// Tag enumeration
int GetTagCount( void )
{ return m_listTags.size(); }
bool GetTagGUID( int index, GUID& guidTag );
bool GetTagName( int index, string& nameTag );
// GUID ID enumeration
int GetIDCountGUID
(
const GUID& tagOwner
);
const char * GetIDNameGUID
(
const GUID& tagOwner,
int idxID,
GUID& valueID
);
// Integer ID enumeration
int GetIDCountInt
(
const GUID& tagOwner
);
const char * GetIDNameInt
(
const GUID& tagOwner,
int idxID,
int& valueID
);
// Implementation
protected:
BYTE * _GetPtrToDataValue( int typePhysical, const PQDIFValue& value );
NI_Tag * _FindTag( const GUID &tag );
NI_ID_GUID * _FindGUID( const GUID& id );
NI_ID_Int * _FindInt( const GUID& tag, int id );
NI_Type * _FindType( INT4 type );
NI_Tag * _LookupTag( int idxLook );
NI_ID_GUID * _LookupGUID
(
const GUID& tagOwner,
int idxLook
);
NI_ID_Int * _LookupInt
(
const GUID& tagOwner,
int idxLook
);
// Data
protected:
CList_NI_Tag m_listTags;
CList_NI_ID_GUID m_listGUIDs;
CList_NI_ID_Int m_listInts;
CList_NI_Type m_listTypes;
// Lookup table for finding the size of a data type.
protected:
static BYTE m_sizeDataTable[70];
};
// The one and only information object (Singleton)
extern CPQDIF_Info theInfo;

View File

@@ -0,0 +1,522 @@
/*
** CPQDIF_COMSupport class. Implements support member functions so that
** make dealing with COM/OLE/ActiveX much easier.
** --------------------------------------------------------------------------
** This class is a Singleton class; this means that only one instance of it
** should ever be created. This instance is made global, and is one of the
** only global objects in the entire system.
** --------------------------------------------------------------------------
**
** File name: $Workfile: pqdsupport.cpp $
** Last modified: $Modtime: 4/15/02 3:19p $
** Last modified by: $Author: Wadef $
**
** VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/pqdsupport.cpp $
** VCS revision: $Revision: 5 $
*/
#ifdef PQDIF_USE_COM
#include "PQDIF_classes.h"
#include "pqdsupport.h"
const GUID ID_NULL = { 0, 0, 0, { 0, 0, 0, 0, 0, 0, 0, 0 } };
// The one and only support object (Singleton)
CPQDIF_COMSupport theSupport;
// Construction
// ============
CPQDIF_COMSupport::CPQDIF_COMSupport()
{
}
CPQDIF_COMSupport::~CPQDIF_COMSupport()
{
}
bool CPQDIF_COMSupport::NewVariantArrayFromGUID
(
VARIANT& var,
const GUID& guid
)
{
bool status = false;
const int countLongs = 4;
BYTE * pbData;
// Set the variant to a 1-byte array
VariantInit( &var );
var.vt = VT_ARRAY + VT_I4;
var.parray = SafeArrayCreateVector( VT_I4, 0, countLongs );
// If a safe array of doubles was passed then ...
if( var.parray != NULL)
{
if( !FAILED( SafeArrayAccessData( var.parray, (void **) &pbData ) ) )
{
// Copy the contents of the GUID
memcpy( pbData, &guid, countLongs * sizeof( long ) );
SafeArrayUnaccessData( var.parray );
status = true;
}
}
return status;
}
bool CPQDIF_COMSupport::SetGUIDFromVariantArray
(
GUID& guid,
const VARIANT& var
) const
{
bool status = false;
long lLower;
long lUpper;
long countItems;
BYTE * pbData;
guid = ID_NULL;
// Valid array of long [ 4 ]?
if( ( var.vt & VT_ARRAY ) /* && ( var.vt & VT_I4 )*/ && var.parray )
{
// Validate the size of the array
SafeArrayGetUBound( var.parray, 1, &lUpper );
SafeArrayGetLBound( var.parray, 1, &lLower );
countItems = (lUpper - lLower + 1);
if( countItems == 4 )
{
VARIANT HUGEP *pvLongs;
if (!FAILED(SafeArrayAccessData(var.parray, reinterpret_cast<void HUGEP**>(&pvLongs))))
{
if (var.vt & VT_VARIANT)
{
INT4 * pInt = (INT4 *)&guid;
for (int count = 0; count < 4; count++, pInt++)
*pInt = pvLongs[count].lVal;
}
else
{
pbData = (BYTE *)pvLongs;
// Copy the GUID
memcpy( &guid, pbData, sizeof( guid ) );
status = true;
}
SafeArrayUnaccessData( var.parray );
}
} // Got safe array data
} // Valid safe array
return status;
}
bool CPQDIF_COMSupport::NewVariantArrayFromVector
(
VARIANT& var,
CPQDIF_E_Vector& vect
)
{
bool status = false;
VARTYPE vtSingle;
long typePhysical;
long sizePhysical;
long countItems;
BYTE * pbData;
INT1 * pdataSource;
// Check the physical type for the size we need...
// (and how many items are in the array)
typePhysical = vect.GetPhysicalType();
sizePhysical = theInfo.GetNumBytesOfType( typePhysical );
vect.GetCount( countItems );
_variant_t varV;
// Grab the first item to see what variant type the array should be...
status = vect.GetValue( 0, varV );
if( status )
{
// Got the variant type
vtSingle = varV.vt;
status = false;
// Set the variant to an array of this type
VariantInit( &var );
var.vt = VT_ARRAY | vtSingle;
var.parray = SafeArrayCreateVector( vtSingle, 0, countItems );
// If a safe array of doubles was passed then ...
if( var.parray != NULL)
{
if( !FAILED( SafeArrayAccessData( var.parray, (void **) &pbData ) ) )
{
pdataSource = reinterpret_cast<INT1 *>(vect.GetRawData());
if( pdataSource )
{
// Copy the entire block of data across by physical item size
memcpy( pbData, pdataSource, countItems * sizePhysical );
status = true;
}
SafeArrayUnaccessData( var.parray );
} // Got safe array data
} // Valid safe array
} // Valid data type
return status;
}
bool CPQDIF_COMSupport::NewVariantArrayFromDouble
(
VARIANT& var,
double * arValues,
long countItems
)
{
bool status = false;
VARTYPE vtSingle;
long sizePhysical;
BYTE * pbData;
// Set the variant to an array of this type
sizePhysical = sizeof( double );
vtSingle = VT_R8;
VariantInit( &var );
var.vt = VT_ARRAY | vtSingle;
var.parray = SafeArrayCreateVector( vtSingle, 0, countItems );
// If a safe array of doubles was passed then ...
if( var.parray != NULL)
{
if( !FAILED( SafeArrayAccessData( var.parray, (void **) &pbData ) ) )
{
if( arValues )
{
// Copy the entire block across
memcpy( pbData, (BYTE *) arValues, sizePhysical * countItems );
status = true;
}
SafeArrayUnaccessData( var.parray );
} // Got safe array data
} // Valid safe array
return status;
}
long GetPhysicalTypeFromVariant( const VARIANT& var, long typeElement )
{
long typePhysical = 0;
BOOL isArray = FALSE;
int countDims = 0;
long lUpper;
long lLower;
long countItemsLastDim = 0;
SAFEARRAY * psa = NULL;
// Is this an array?
if( var.vt & VT_ARRAY )
{
// Which safearray?
if( var.vt & VT_BYREF )
{
if( var.pparray )
psa = *var.pparray;
}
else
{
psa = var.parray;
}
if( psa )
{
isArray = TRUE;
countDims = SafeArrayGetDim( psa );
// Count the number of items in the last dimension...
SafeArrayGetUBound( var.parray, countDims, &lUpper );
SafeArrayGetLBound( var.parray, countDims, &lLower );
countItemsLastDim = (lUpper - lLower + 1);
}
}
// Is this a vector? If so, we only consider it an "array" if there
// are two dimensions.
if( typeElement == ID_ELEMENT_TYPE_VECTOR && isArray )
{
if( countDims < 2 )
{
isArray = FALSE;
}
}
switch( var.vt & VT_TYPEMASK )
{
case VT_BOOL:
typePhysical = ID_PHYS_TYPE_BOOLEAN2 ;
break;
case VT_I1:
typePhysical = ID_PHYS_TYPE_INTEGER1 ;
break;
case VT_I2:
typePhysical = ID_PHYS_TYPE_INTEGER2 ;
break;
case VT_I4:
typePhysical = ID_PHYS_TYPE_INTEGER4 ;
if( isArray && countItemsLastDim == 4 )
{
typePhysical = ID_PHYS_TYPE_GUID;
}
break;
// Real/complex
case VT_R4:
typePhysical = ID_PHYS_TYPE_REAL4 ;
if( isArray && countItemsLastDim == 2 )
{
typePhysical = ID_PHYS_TYPE_COMPLEX8;
}
break;
case VT_R8:
typePhysical = ID_PHYS_TYPE_REAL8;
if( isArray && countItemsLastDim == 2 )
{
typePhysical = ID_PHYS_TYPE_COMPLEX16;
}
break;
// Date/time
case VT_DATE:
typePhysical = ID_PHYS_TYPE_TIMESTAMPPQDIF ;
break;
}
return typePhysical;
}
bool CPQDIF_COMSupport::SetVectorArrayFromVariant( CPQDIF_E_Vector& vect, VARIANT& values )
{
bool status = false;
long typePhysical;
unsigned int sizeSingle;
long sizeType;
BYTE * pbData;
INT1 * pdataTarget;
SAFEARRAY * psa = NULL;
long lLower;
long lUpper;
long countItems;
long countDimensions;
long countItemsDim2 = 0;
// Make sure it is an array
if( values.vt & VT_ARRAY )
{
// Is valid physical type set?
//typePhysical = vect.GetPhysicalType();
typePhysical = 0;
if( typePhysical == 0 )
{
typePhysical = GetPhysicalTypeFromVariant(
values, vect.GetElementType() );
vect.SetPhysicalType( typePhysical );
sizeType = theInfo.GetNumBytesOfType( typePhysical );
}
// Which safearray?
if( values.vt & VT_BYREF )
{
if( values.pparray )
psa = *values.pparray;
}
else
{
psa = values.parray;
}
if( !FAILED( SafeArrayAccessData( psa, (void **)&pbData ) ) )
{
// Get the physical size of each element
sizeSingle = SafeArrayGetElemsize( values.parray );
// Get the size of the new array.
SafeArrayGetUBound( values.parray, 1, &lUpper );
SafeArrayGetLBound( values.parray, 1, &lLower );
countItems = (lUpper - lLower + 1);
// Is there a second dimension?
countDimensions = SafeArrayGetDim( values.parray );
if( countDimensions > 1 )
{
SafeArrayGetUBound( values.parray, 2, &lUpper );
SafeArrayGetLBound( values.parray, 2, &lLower );
countItemsDim2 = (lUpper - lLower + 1);
}
// Configure vector
vect.SetCount( countItems );
pdataTarget = reinterpret_cast<INT1 *>(vect.GetRawData());
if( pdataTarget && (int) sizeType == (int) sizeSingle )
{
// Copy the caller's data into the array.
memcpy( pdataTarget, pbData, countItems * sizeSingle );
status = true;
}
SafeArrayUnaccessData( psa );
}
}
return status;
}
bool CPQDIF_COMSupport::NewArrayUINT4FromVariant
(
UINT4 ** aidxChannelTriggerLocal,
long& countItems,
VARIANT& var
)
{
bool status = false;
long lLower;
long lUpper;
BYTE * pbData;
long * pSource;
UINT4 * pTarget;
// Init
*aidxChannelTriggerLocal = NULL;
countItems = 0;
// Valid array of long?
if( ( var.vt & VT_ARRAY ) && ( var.vt & VT_I4 ) && var.parray )
{
// Validate the size of the array
SafeArrayGetUBound( var.parray, 1, &lUpper );
SafeArrayGetLBound( var.parray, 1, &lLower );
countItems = (lUpper - lLower + 1);
if( countItems > 0 )
{
if( !FAILED( SafeArrayAccessData( var.parray, (void **) &pbData ) ) )
{
// Allocate space
*aidxChannelTriggerLocal = new UINT4[ countItems ];
// Create temp pointers (to be incremented) and copy
pSource = (long *) pbData;
pTarget = *aidxChannelTriggerLocal;
for( long idx = 0; idx < countItems; idx++, pSource++, pTarget++ )
{
*pTarget = (UINT4) *pSource;
}
status = true;
SafeArrayUnaccessData( var.parray );
}
} // Got safe array data
} // Valid safe array
return status;
}
bool CPQDIF_COMSupport::NewComStringFromVector( CPQDIF_E_Vector& vect, BSTR * str )
{
bool status = false;
long countItems;
string strOutput;
INT1 * pdataSource;
// Init
strOutput = "";
vect.GetCount( countItems );
switch( vect.GetPhysicalType() )
{
case ID_PHYS_TYPE_CHAR1:
pdataSource = reinterpret_cast<INT1 *>(vect.GetRawData());
if( pdataSource )
{
// Convert it to a string
USES_CONVERSION;
strOutput = (const char *) pdataSource;
*str = SysAllocString(_bstr_t(strOutput.c_str()));
status = true;
}
break;
case ID_PHYS_TYPE_CHAR2:
// NOT SUPPORTED
break;
default:
status = true;
break;
}
return status;
}
bool CPQDIF_COMSupport::SetVectorArrayFromString( CPQDIF_E_Vector& vect, BSTR * str )
{
bool status = false;
USES_CONVERSION;
// Init
vect.SetValues( W2A(*str) );
return status;
}
bool CPQDIF_COMSupport::SetDateFromTimeStamp( DATE& date, const TIMESTAMPPQDIF& ts )
{
date = (double) ts.day
+ ( (double) ts.sec / (double) SECONDS_PER_DAY );
return true;
}
bool CPQDIF_COMSupport::SetTimeStampFromDate( TIMESTAMPPQDIF& ts, const DATE& date )
{
// Take integral portion for the day
ts.day = (UINT4) date;
// Take the fractional portion for the seconds
ts.sec = ( (REAL8) SECONDS_PER_DAY ) * ( (REAL8) date - (REAL8) ts.day );
return true;
}
#endif // PQDIF_USE_COM

View File

@@ -0,0 +1,64 @@
#ifndef _CPQDIF_COMSupport_INC_
#define _CPQDIF_COMSupport_INC_
// class CPQDIF_COMSupport
#ifdef PQDIF_USE_COM
class CPQDIF_COMSupport
{
public:
CPQDIF_COMSupport();
~CPQDIF_COMSupport();
// Attributes
public:
// Operations
public:
bool NewVariantArrayFromGUID
(
VARIANT& var,
const GUID& guid
);
bool SetGUIDFromVariantArray
(
GUID& guid,
const VARIANT& var
) const;
bool NewVariantArrayFromVector
(
VARIANT& var,
CPQDIF_E_Vector& vect
);
bool NewVariantArrayFromDouble
(
VARIANT& var,
double * arValues,
long countValues
);
bool NewArrayUINT4FromVariant
(
UINT4 ** aidxChannelTrigger,
long& countTriggersLocal,
VARIANT& aidxChannelTriggerVar
);
bool SetVectorArrayFromVariant( CPQDIF_E_Vector& vect, VARIANT& var );
bool NewComStringFromVector( CPQDIF_E_Vector& vect, BSTR * str );
bool SetVectorArrayFromString( CPQDIF_E_Vector& vect, BSTR * str );
bool SetDateFromTimeStamp( DATE& date, const TIMESTAMPPQDIF& ts );
bool SetTimeStampFromDate( TIMESTAMPPQDIF& ts, const DATE& date );
// Implementation
protected:
};
// The one and only support object (Singleton)
extern CPQDIF_COMSupport theSupport;
#endif // PQDIF_USE_COM
#endif // _CPQDIF_COMSupport_INC_

View File

@@ -0,0 +1,208 @@
// File name: $Workfile: pqptrarray.cpp $
// Last modified: $Modtime: 2/10/99 12:42 $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/pqptrarray.cpp $
// VCS revision: $Revision: 5 $
#include "PQDIF_classes.h"
const int sizeElement = sizeof( void * );
CPQPtrArray::CPQPtrArray()
{
m_data = (void **) malloc( 16 * sizeElement );
m_size = 0;
m_max = 16;
m_growBy = 16;
}
CPQPtrArray::~CPQPtrArray()
{
if( m_data )
{
free( m_data );
}
}
int CPQPtrArray::GetSize( void ) const
{
return m_size;
}
void CPQPtrArray::SetSize( int NewSize, int GrowBy )
{
m_size = NewSize;
if( GrowBy > 0 )
m_growBy = GrowBy;
// Grow?
if( NewSize > m_max )
{
m_max = NewSize + m_growBy;
m_data = (void **) realloc( (void *) m_data, m_max * sizeElement );
}
}
void * CPQPtrArray::GetAt( int idx ) const
{
void * bogus = NULL;
if( idx >=0 && idx < m_size )
{
return m_data[ idx ];
}
else
{
return bogus;
}
}
void CPQPtrArray::SetAt( int idx, void * value )
{
if( idx >= 0 && idx < m_size )
{
m_data[ idx ] = value;
}
}
void CPQPtrArray::SetAtGrow(int nIndex, void* newElement)
{
//ASSERT_VALID(this);
//ASSERT(nIndex >= 0);
if (nIndex >= m_size)
SetSize(nIndex+1);
m_data[nIndex] = newElement;
}
void CPQPtrArray::InsertAt( int nIndex, void * newElement, int nCount )
{
if (nIndex >= m_size)
{
// adding after the end of the array
SetSize(nIndex + nCount); // grow so indexToInsert is valid
}
else
{
// inserting in the middle of the array
int nOldSize = m_size;
SetSize(m_size + nCount); // grow it to new size
// shift old data up to fill gap
memmove(&m_data[nIndex+nCount], &m_data[nIndex],
(nOldSize-nIndex) * sizeof(void*));
// re-init slots we copied from
memset(&m_data[nIndex], 0, nCount * sizeof(void*));
}
// insert new value in the gap
//ASSERT(nIndex + nCount <= m_size);
while (nCount--)
m_data[nIndex++] = newElement;
}
void CPQPtrArray::RemoveAt( int indexToRemove )
{
if( indexToRemove >= 0 && indexToRemove < m_size )
{
for( int idx = indexToRemove + 1; idx < m_size; idx++ )
{
m_data[ idx - 1 ] = m_data[ idx ];
}
SetSize( GetSize() - 1 );
}
}
int CPQPtrArray::Add( void * value )
{
int pos = m_size;
SetSize( m_size + 1, m_growBy );
if( m_data )
{
m_data[ pos ] = value;
return pos;
}
else
{
return -1;
}
}
void * CPQPtrArray::operator[] ( int idx ) const
{
return GetAt( idx );
}
#ifdef _DEBUG
bool CPQPtrArray::Test( void )
{
bool failed = false;
void * ptr1 = (void *) 1;
void * ptr2 = (void *) 2;
void * ptr3 = (void *) 3;
void * ptr4 = (void *) 4;
void * ptr5 = (void *) 5;
SetSize( 16, 4 );
if( m_size != 16 || m_growBy != 4 )
failed = true;
SetSize( 0 );
if( m_size != 0 || m_growBy != 4 )
failed = true;
Add( ptr1 );
Add( ptr2 );
if( m_size != 2 )
failed = true;
if( m_data[0] != ptr1 || m_data[1] != ptr2 )
failed = true;
Add( ptr3 );
InsertAt( 1, ptr4 );
if( m_size != 4 )
failed = true;
if( m_data[0] != ptr1 || m_data[1] != ptr4 || m_data[2] != ptr2 || m_data[3] != ptr3 )
failed = true;
SetSize( 2, 16 );
if( m_size != 2 )
failed = true;
if( m_growBy != 16 )
failed = true;
if( m_data[0] != ptr1 || m_data[1] != ptr4 )
failed = true;
SetSize( 3 );
if( m_size != 3 )
failed = true;
if( m_growBy != 16 )
failed = true;
if( failed )
{
//TRACE( "CPQPtrArray::Test - *FAILED*" );
return false;
}
return true;
}
#endif

View File

@@ -0,0 +1,39 @@
// File name: $Workfile: pqptrarray.h $
// Last modified: $Modtime: 1/03/99 7:27p $
// Last modified by: $Author: Erich $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/pqptrarray.h $
// VCS revision: $Revision: 3 $
class CPQPtrArray
{
public:
CPQPtrArray();
~CPQPtrArray();
public:
int GetSize( void ) const;
void SetSize( int NewSize, int GrowBy = -1 );
void * GetAt( int idx ) const;
void SetAt( int idx, void * value );
void SetAtGrow( int idx, void * value );
void InsertAt( int indexToInsert, void * prec, int nCount = 1 );
void RemoveAt( int indexToInsert );
int Add( void * value );
void * operator[] ( int idx ) const;
#ifdef _DEBUG
bool Test( void );
#endif
protected:
void ** m_data;
int m_size;
int m_max;
int m_growBy;
};

View File

@@ -0,0 +1,42 @@
/*
** CPQDIF_StreamProcessor class. Base class for PQDIF stream processors --
** generally for compression/decompression.
** --------------------------------------------------------------------------
**
** File name: $Workfile: proc_bas.cpp $
** Last modified: $Modtime: 9/20/00 10:16a $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/proc_bas.cpp $
** VCS revision: $Revision: 6 $
*/
#include "PQDIF_classes.h"
#include "zlib.h"
// Construction
// ============
CPQDIF_StreamProcessor::CPQDIF_StreamProcessor()
{
m_pstrm = NULL;
m_checksum = adler32( 0L, Z_NULL, 0 );
}
CPQDIF_StreamProcessor::~CPQDIF_StreamProcessor()
{
}
bool CPQDIF_StreamProcessor::ConnectStream( CPQDIF_StreamIO * pstrm )
{
m_pstrm = pstrm;
return true;
}
void CPQDIF_StreamProcessor::ResetChecksum( void )
{
m_checksum = adler32( 0L, Z_NULL, 0 );
}

View File

@@ -0,0 +1,37 @@
// File name: $Workfile: proc_bas.h $
// Last modified: $Modtime: 9/20/00 10:14a $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/proc_bas.h $
// VCS revision: $Revision: 5 $
// Interface class CPQDIF_StreamProcessor
class CPQDIF_StreamIO;
class CPQDIF_StreamProcessor
{
public:
CPQDIF_StreamProcessor();
virtual ~CPQDIF_StreamProcessor();
// Attributes
public:
virtual long GetChecksum( void ) { return m_checksum; }
// Operations
public:
virtual bool ConnectStream( CPQDIF_StreamIO * pstrm );
virtual bool StreamEncode( void ) = 0;
virtual bool StreamDecode( void ) = 0;
virtual void ResetChecksum( void );
// Implementation
protected:
// Member data
protected:
CPQDIF_StreamIO * m_pstrm;
long m_checksum;
};

View File

@@ -0,0 +1,61 @@
/*
** CPQDIF_SP_Nothing class. Implements a "do nothing" processor.
** Used when the PQDIF file is not compressed -- or for certain records
** which are never compressed.
** --------------------------------------------------------------------------
**
** File name: $Workfile: proc_not.cpp $
** Last modified: $Modtime: 9/20/00 10:22a $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/proc_not.cpp $
** VCS revision: $Revision: 6 $
*/
#include "PQDIF_classes.h"
#include "zlib.h"
// Construction
// ============
CPQDIF_SP_Nothing::CPQDIF_SP_Nothing()
{
}
CPQDIF_SP_Nothing::~CPQDIF_SP_Nothing()
{
}
bool CPQDIF_SP_Nothing::StreamEncode( void )
{
bool status = FALSE;
long sizeActual = 0;
const BYTE * bufferInput;
BYTE * bufferOutput;
status = m_pstrm->ProcessRead( bufferInput, 0, sizeActual );
if( status )
{
status = m_pstrm->ProcessWriteReserve( bufferOutput, sizeActual );
if( status )
{
memcpy( bufferOutput, bufferInput, sizeActual );
m_checksum = adler32( m_checksum, (const Bytef *)bufferInput, sizeActual );
m_pstrm->ProcessWriteRelease( sizeActual );
}
}
return status;
}
bool CPQDIF_SP_Nothing::StreamDecode( void )
{
bool status = FALSE;
// Since we're doing nothing, decoding is the same
// as encoding!
status = StreamEncode();
return status;
}

View File

@@ -0,0 +1,24 @@
// File name: $Workfile: proc_not.h $
// Last modified: $Modtime: 2/05/98 2:48p $
// Last modified by: $Author: Rob $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/proc_not.h $
// VCS revision: $Revision: 3 $
// class CPQDIF_SP_Nothing
class CPQDIF_SP_Nothing : public CPQDIF_StreamProcessor
{
public:
CPQDIF_SP_Nothing();
~CPQDIF_SP_Nothing();
// Attributes
public:
// Operations
public:
virtual bool StreamEncode( void );
virtual bool StreamDecode( void );
};

View File

@@ -0,0 +1,168 @@
/*
** CPQDIF_SP_ZLIB class. Implements a compression processor for the ZLIB
** compression library. See PQDIF documentation for details.
** --------------------------------------------------------------------------
**
** File name: $Workfile: proc_zlib.cpp $
** Last modified: $Modtime: 10/11/01 12:43p $
** Last modified by: $Author: Tomm $
**
** VCS archive path: $Archive: /ElectrotekLibs/Borland/PQDIFlib/proc_zlib.cpp $
** VCS revision: $Revision: 9 $
*/
#include "PQDIF_classes.h"
// Public-domain ZLIB code
#include "zlib.h"
// Construction
// ============
CPQDIF_SP_ZLIB::CPQDIF_SP_ZLIB()
{
}
CPQDIF_SP_ZLIB::~CPQDIF_SP_ZLIB()
{
}
bool CPQDIF_SP_ZLIB::StreamEncode( void )
{
bool status = TRUE;
bool haveData = FALSE;
long sizeActual = 0;
z_stream c_stream; /* compression stream */
int err;
// Init ZLIB for best compression ratio
memset( &c_stream, 0, sizeof( c_stream ) );
c_stream.zalloc = (alloc_func)0;
c_stream.zfree = (free_func)0;
c_stream.opaque = (voidpf)0;
err = deflateInit( &c_stream, Z_BEST_COMPRESSION );
if( err == Z_OK )
{
// Initialize the input buffer.
const BYTE * bufferInput;
long sizeInput;
status = m_pstrm->ProcessRead( bufferInput, 0, sizeInput );
c_stream.next_in = (BYTE *)bufferInput;
c_stream.avail_in = sizeInput;
if( status )
{
// Reserve space in the stream buffer for output.
// If successful then ...
BYTE * bufferOutput;
int sizeOutput = ( ( sizeInput * 11 )/10 ) + 12;
status = m_pstrm->ProcessWriteReserve( bufferOutput, sizeOutput );
c_stream.next_out = bufferOutput;
c_stream.avail_out = sizeOutput;
c_stream.total_out = 0;
if( status )
{
// Compress!
err = deflate( &c_stream, Z_FINISH );
if( err != Z_STREAM_END )
status = false;
// Release the output buffer.
if( status && c_stream.total_out > 0 )
{
m_checksum = adler32( m_checksum, (const Bytef *)bufferOutput, c_stream.total_out );
status = m_pstrm->ProcessWriteRelease( c_stream.total_out );
}
}
}
}
else
status = false;
err = deflateEnd(&c_stream);
if( err != Z_OK )
status = FALSE;
return status;
}
bool CPQDIF_SP_ZLIB::StreamDecode( void )
{
bool status = TRUE;
bool haveData = FALSE;
long sizeActual = 0;
z_stream c_stream; /* decompression stream */
int err;
// Init
memset( &c_stream, 0, sizeof( c_stream ) );
err = inflateInit(&c_stream);
if( err == Z_OK )
{
// Initialize the input buffer.
const BYTE * bufferInput;
long sizeInput;
status = m_pstrm->ProcessRead( bufferInput, 0, sizeInput );
c_stream.next_in = (BYTE *)bufferInput;
c_stream.avail_in = sizeInput;
// Determine the size of the output buffer to use for expanding
// the data.
BYTE * bufferOutput;
int sizeOutput = max( ( c_stream.avail_in * 4 ), (unsigned) 32*1024 );
while( status && err == Z_OK )
{
// Reserve space in the stream buffer for output.
// If successful then ...
status = m_pstrm->ProcessWriteReserve( bufferOutput, sizeOutput );
c_stream.next_out = bufferOutput;
c_stream.avail_out = sizeOutput;
c_stream.total_out = 0;
if( status )
{
// Compress!
err = inflate( &c_stream, Z_NO_FLUSH );
// Release the output buffer.
status = m_pstrm->ProcessWriteRelease( c_stream.total_out );
}
}
}
else
status = FALSE;
err = inflateEnd( &c_stream );
if( err != Z_OK )
status = FALSE;
return status;
}

View File

@@ -0,0 +1,29 @@
// File name: $Workfile: proc_zlib.h $
// Last modified: $Modtime: 2/05/98 2:48p $
// Last modified by: $Author: Rob $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/proc_zlib.h $
// VCS revision: $Revision: 3 $
// class CPQDIF_SP_ZLIB
class CPQDIF_SP_ZLIB : public CPQDIF_StreamProcessor
{
public:
CPQDIF_SP_ZLIB();
~CPQDIF_SP_ZLIB();
// Attributes
public:
// Operations
public:
virtual bool StreamEncode( void );
virtual bool StreamDecode( void );
// Member data
private:
BYTE * m_bufferOutput;
int m_sizeOutput;
};

View File

@@ -0,0 +1,147 @@
/*
** CPQDIF_R_DataSource class. Implements a PQDIF record "wrapper" for the
** data source record. You can cast a standard record object to this class.
** --------------------------------------------------------------------------
**
** File name: $Workfile: rec_base.cpp $
** Last modified: $Modtime: 11/14/00 3:36p $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/rec_base.cpp $
** VCS revision: $Revision: 7 $
*/
#include "PQDIF_classes.h"
CPQDIF_E_Collection * CPQDIFRecord::FindCollectionInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag
)
{
CPQDIF_E_Collection * pcolReturn = NULL;
if( pcoll )
{
pcolReturn = (CPQDIF_E_Collection *)pcoll->GetElement( tag, ID_ELEMENT_TYPE_COLLECTION );
}
return pcolReturn;
}
CPQDIF_E_Scalar * CPQDIFRecord::FindScalarInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag
)
{
CPQDIF_E_Scalar * pscReturn = NULL;
if( pcoll )
{
pscReturn = (CPQDIF_E_Scalar *)pcoll->GetElement( tag, ID_ELEMENT_TYPE_SCALAR );
}
return pscReturn;
}
bool CPQDIFRecord::GetScalarValueInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag,
UINT4 typePhysical,
PQDIFValue& value
)
{
bool status = FALSE;
long typePhysicalThisItem;
CPQDIF_E_Scalar * pscReturn = NULL;
if( pcoll )
{
pscReturn = (CPQDIF_E_Scalar *)pcoll->GetElement( tag, ID_ELEMENT_TYPE_SCALAR );
if( pscReturn )
{
status = pscReturn->GetValue( typePhysicalThisItem, value )
&& typePhysicalThisItem == (long)typePhysical;
}
}
return status;
}
CPQDIF_E_Scalar * CPQDIFRecord::FindOrCreateScalarInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag,
UINT4 typePhysical
)
{
CPQDIF_E_Scalar * pscReturn = NULL;
if( pcoll )
{
pscReturn = (CPQDIF_E_Scalar *)pcoll->GetElement( tag, ID_ELEMENT_TYPE_SCALAR );
if( !pscReturn )
{
// If it doesn't exist, create, initialize and add it
pscReturn = (CPQDIF_E_Scalar *) theFactory.NewElement( ID_ELEMENT_TYPE_SCALAR );
if( pscReturn )
{
pscReturn->SetTag( tag );
pscReturn->SetPhysicalType( typePhysical );
pcoll->Add( pscReturn );
}
}
}
return pscReturn;
}
CPQDIF_E_Vector * CPQDIFRecord::FindVectorInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag
)
{
CPQDIF_E_Vector * pvectReturn = NULL;
if( pcoll )
{
pvectReturn = (CPQDIF_E_Vector *)pcoll->GetElement( tag, ID_ELEMENT_TYPE_VECTOR );
}
return pvectReturn;
}
CPQDIF_E_Vector * CPQDIFRecord::FindOrCreateVectorInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag,
UINT4 typePhysical
)
{
CPQDIF_E_Vector * pvectReturn = NULL;
if( pcoll )
{
pvectReturn = (CPQDIF_E_Vector *)pcoll->GetElement( tag, ID_ELEMENT_TYPE_VECTOR );
if( !pvectReturn )
{
// If it doesn't exist, create, initialize and add it
pvectReturn = (CPQDIF_E_Vector *) theFactory.NewElement( ID_ELEMENT_TYPE_VECTOR );
if( pvectReturn )
{
pvectReturn->SetTag( tag );
pvectReturn->SetPhysicalType( typePhysical );
pcoll->Add( pvectReturn );
}
}
}
return pvectReturn;
}

View File

@@ -0,0 +1,99 @@
/*
** Base class for PQDIF records; pure virtual.
** --------------------------------------------------------------------------
**
** File name: $Workfile: rec_base.h $
** Last modified: $Modtime: 2/05/98 1:53p $
** Last modified by: $Author: Rob $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/rec_base.h $
** VCS revision: $Revision: 4 $
*/
// Forward-declare these items
class CPQDIF_StreamIO;
class CPQDIF_E_Collection;
class CPQDIF_E_Scalar;
class CPQDIF_E_Vector;
union PQDIFValue;
class CPQDIFRecord
{
public:
CPQDIFRecord() {}
virtual ~CPQDIFRecord() {}
// Operations
public:
virtual bool ReadHeader( CPQDIF_StreamIO * pstream ) = 0;
virtual bool ReadBody( CPQDIF_StreamIO * pstream ) = 0;
virtual bool WriteHeader( CPQDIF_StreamIO * pstream ) = 0;
virtual bool WriteBody( CPQDIF_StreamIO * pstream ) = 0;
// Attributes
public:
virtual bool HeaderGetPos( LINKABS4& pos ) const = 0;
virtual bool HeaderSetPos( LINKABS4 pos ) = 0;
virtual bool HeaderGetTag( GUID& tagRecord ) const = 0;
virtual bool HeaderSetTag( GUID tagRecord ) = 0;
virtual bool HeaderGetSize( SIZE4& sizeHeader, SIZE4& sizeBody ) const = 0;
virtual bool HeaderSetSize( SIZE4 sizeHeader, SIZE4 sizeBody ) = 0;
virtual bool HeaderGetChecksum( UINT& checksum ) const = 0;
virtual bool HeaderSetChecksum( UINT checksum ) = 0;
virtual bool HeaderGetPosNextRecord( LINKABS4& pos ) const = 0;
virtual bool HeaderSetPosNextRecord( LINKABS4 pos ) = 0;
virtual CPQDIF_E_Collection * GetMainCollection( void ) const = 0;
virtual bool SetMainCollection( CPQDIF_E_Collection * collMain ) = 0;
virtual bool GetChanged( void ) = 0;
virtual void SetChanged( bool changed ) = 0;
// Static functions (do not affect--or even require--an object)
public:
static CPQDIF_E_Collection * FindCollectionInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag
);
static CPQDIF_E_Scalar * FindScalarInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag
);
static bool GetScalarValueInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag,
UINT4 typePhysical,
PQDIFValue& value
);
static CPQDIF_E_Vector * FindVectorInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag
);
static CPQDIF_E_Scalar * FindOrCreateScalarInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag,
UINT4 typePhysical
);
static CPQDIF_E_Vector * FindOrCreateVectorInCollection
(
CPQDIF_E_Collection * pcoll,
const GUID& tag,
UINT4 typePhysical
);
// Implementation
protected:
// None; pure virtual base class.
// Member data
protected:
// None; pure virtual base class.
};

View File

@@ -0,0 +1,211 @@
/*
** CPQDIF_R_Container class. Implements a PQDIF record "wrapper" for the
** data source record. You can cast a standard record object to this class.
** --------------------------------------------------------------------------
**
** File name: $Workfile: rec_container.cpp $
** Last modified: $Modtime: 7/07/99 8:11p $
** Last modified by: $Author: Erich $
**
** VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/rec_container.cpp $
** VCS revision: $Revision: 2 $
*/
#include "PQDIF_classes.h"
// Operations
bool CPQDIF_R_Container::GetCompressionInfo
(
UINT4& styleComp, // Compression style (output)
UINT4& algComp // Compression algorithm (output)
)
{
bool status = false;
GUID tagRecord;
PQDIFValue value;
// Verify that the record has the right header tag
status = HeaderGetTag( tagRecord );
if( status && PQDIF_IsEqualGUID( tagRecord, tagContainer) && m_pcollMain )
{
// It's the right type of record.
//
status = GetScalarValueInCollection( m_pcollMain,
tagCompressionStyleID, ID_PHYS_TYPE_UNS_INTEGER4, value );
if( status )
{
// We got compression style.
styleComp = value.uint4;
// Now try to get compression algorithm
status = GetScalarValueInCollection( m_pcollMain,
tagCompressionAlgorithmID, ID_PHYS_TYPE_UNS_INTEGER4, value );
if( status )
{
// We got compression algorithm. All done.
algComp = value.uint4;
}
}
}
return status;
}
bool CPQDIF_R_Container::SetInfo
(
const char * language,
const char * title,
const char * subject,
const char * author,
const char * keywords,
const char * comments,
const char * lastSavedBy,
const char * application,
const char * security,
const char * owner,
const char * copyright,
const char * trademarks,
const char * notes
)
{
bool rc = false;
if( m_pcollMain )
{
// Add string entries
m_pcollMain->SetVectorString( tagLanguage, language );
m_pcollMain->SetVectorString( tagTitle, title );
m_pcollMain->SetVectorString( tagSubject, subject );
m_pcollMain->SetVectorString( tagAuthor, author );
m_pcollMain->SetVectorString( tagKeywords, keywords );
m_pcollMain->SetVectorString( tagComments, comments );
m_pcollMain->SetVectorString( tagLastSavedBy, lastSavedBy );
m_pcollMain->SetVectorString( tagApplication, application );
m_pcollMain->SetVectorString( tagSecurity, security );
m_pcollMain->SetVectorString( tagOwner, owner );
m_pcollMain->SetVectorString( tagCopyright, copyright );
m_pcollMain->SetVectorString( tagTrademarks, trademarks );
m_pcollMain->SetVectorString( tagNotes, notes );
rc = true;
}
return rc;
}
bool CPQDIF_R_Container::SetInfo1
(
const char * language,
const char * title,
const char * subject,
const char * author,
const char * keywords,
const char * comments,
const char * lastSavedBy,
const char * application,
const char * security,
const char * owner,
const char * copyright,
const char * trademarks,
const char * notes,
const char * ApplicationVersion,
const char * SystemName,
const char * SystemVersion
)
{
bool rc = false;
if( m_pcollMain )
{
// Add string entries
m_pcollMain->SetVectorString( tagLanguage, language );
m_pcollMain->SetVectorString( tagTitle, title );
m_pcollMain->SetVectorString( tagSubject, subject );
m_pcollMain->SetVectorString( tagAuthor, author );
m_pcollMain->SetVectorString( tagKeywords, keywords );
m_pcollMain->SetVectorString( tagComments, comments );
m_pcollMain->SetVectorString( tagLastSavedBy, lastSavedBy );
m_pcollMain->SetVectorString( tagApplication, application );
m_pcollMain->SetVectorString( tagSecurity, security );
m_pcollMain->SetVectorString( tagOwner, owner );
m_pcollMain->SetVectorString( tagCopyright, copyright );
m_pcollMain->SetVectorString( tagTrademarks, trademarks );
m_pcollMain->SetVectorString( tagNotes, notes );
m_pcollMain->SetVectorString( tagApplicationVersion, ApplicationVersion );
m_pcollMain->SetVectorString( tagSystemName, SystemName );
m_pcollMain->SetVectorString( tagSystemVersion, SystemVersion );
rc = true;
}
return rc;
}
bool CPQDIF_R_Container::GetTagFileName(string& strFileName)
{
bool status = FALSE;
CPQDIF_E_Collection * pcollMain = m_pcollMain;
CPQDIF_E_Vector * pvect;
if( pcollMain )
{
// Find strings
pvect = FindVectorInCollection( pcollMain, tagFileName );
if( pvect ) pvect->GetValues( strFileName );
status = TRUE;
}
return status;
}
bool CPQDIF_R_Container::SetTimeCreationAndTimeLastSaved
(
const TIMESTAMPPQDIF& timeCreation,
const TIMESTAMPPQDIF& timeLastSaved
)
{
bool status = false;
CPQDIF_E_Scalar * psc;
CPQDIF_E_Vector * pvect;
// Init
if (m_pcollMain == NULL)
return false;
// First, find (or create) the trigger method
psc = FindOrCreateScalarInCollection(m_pcollMain,
tagCreation, ID_PHYS_TYPE_TIMESTAMPPQDIF);
// Set its value
if (psc)
{
status = psc->SetValueTimeStamp(timeCreation);
}
// Set the time it was triggered
if (status)
{
status = false;
psc = FindOrCreateScalarInCollection(m_pcollMain,
tagLastSaved, ID_PHYS_TYPE_TIMESTAMPPQDIF);
// Set value
if (psc)
{
status = psc->SetValueTimeStamp(timeLastSaved);
}
}
return status;
}

View File

@@ -0,0 +1,76 @@
/*
** class CPQDIF_R_Container
** --------------------------------------------------------------------------
**
** File name: $Workfile: rec_container.h $
** Last modified: $Modtime: 7/07/99 8:12p $
** Last modified by: $Author: Erich $
**
** VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/rec_container.h $
** VCS revision: $Revision: 3 $
*/
class CPQDIF_R_Container : public CPQDIF_R_General
{
public:
CPQDIF_R_Container();
virtual ~CPQDIF_R_Container();
// Operations
public:
bool GetTagFileName(string& strFileName);
bool GetInfo();
bool SetInfo
(
const char * language,
const char * title,
const char * subject,
const char * author,
const char * keywords,
const char * comments,
const char * lastSavedBy,
const char * application,
const char * security,
const char * owner,
const char * copyright,
const char * trademarks,
const char * notes
);
bool SetInfo1
(
const char * language,
const char * title,
const char * subject,
const char * author,
const char * keywords,
const char * comments,
const char * lastSavedBy,
const char * application,
const char * security,
const char * owner,
const char * copyright,
const char * trademarks,
const char * notes,
const char * ApplicationVersion,
const char * SystemName,
const char * SystemVersion
);
bool GetCompressionInfo
(
UINT4& styleComp, // Compression style (output)
UINT4& algComp // Compression algorithm (output)
);
bool SetTimeCreationAndTimeLastSaved
(
const TIMESTAMPPQDIF& timeCreation,
const TIMESTAMPPQDIF& timeLastSaved
);
// Local data
private:
};

View File

@@ -0,0 +1,887 @@
/*
** CPQDIF_R_DataSource class. Implements a PQDIF record "wrapper" for the
** data source record. You can cast a standard record object to this class.
** --------------------------------------------------------------------------
**
** File name: $Workfile: rec_datasource.cpp $
** Last modified: $Modtime: 5/25/99 10:56a $
** Last modified by: $Author: Jack $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/rec_datasource.cpp $
** VCS revision: $Revision: 14 $
*/
#include "PQDIF_classes.h"
// Operations
bool CPQDIF_R_DataSource::GetInfo
(
GUID& idDataSourceType,
GUID& idVendor,
GUID& idEquipment,
string& serialNumber,
string& version,
string& name,
string& owner,
string& location,
string& timeZone
)
{
bool status = FALSE;
CPQDIF_E_Collection * pcollMain = m_pcollMain;
CPQDIF_E_Scalar * psc;
CPQDIF_E_Vector * pvect;
if( pcollMain )
{
// Find GUIDs
psc = FindScalarInCollection( pcollMain, tagDataSourceTypeID );
if( psc ) psc->GetValueGUID( idDataSourceType );
psc = FindScalarInCollection( pcollMain, tagVendorID );
if( psc ) psc->GetValueGUID( idVendor );
psc = FindScalarInCollection( pcollMain, tagEquipmentID );
if( psc ) psc->GetValueGUID( idEquipment );
// Find strings
pvect = FindVectorInCollection( pcollMain, tagSerialNumberDS );
if( pvect ) pvect->GetValues( serialNumber );
pvect = FindVectorInCollection( pcollMain, tagVersionDS );
if( pvect ) pvect->GetValues( version );
pvect = FindVectorInCollection( pcollMain, tagNameDS );
if( pvect ) pvect->GetValues( name );
pvect = FindVectorInCollection( pcollMain, tagOwnerDS );
if( pvect ) pvect->GetValues( owner );
pvect = FindVectorInCollection( pcollMain, tagLocationDS );
if( pvect ) pvect->GetValues( location );
pvect = FindVectorInCollection( pcollMain, tagTimeZoneDS );
if( pvect ) pvect->GetValues( timeZone );
status = TRUE;
}
return status;
}
long CPQDIF_R_DataSource::GetCountChannelDefns( void )
{
long count = 0;
CPQDIF_E_Collection * pcollDefns;
pcollDefns = GetChannelDefns();
if( pcollDefns )
{
// Is this the right tag?
const char * pname;
pname = theInfo.GetNameOfTag( pcollDefns->GetTag() );
count = pcollDefns->GetCount();
}
return count;
}
long CPQDIF_R_DataSource::GetCountSeriesDefns( int idxChannelDefn )
{
long count = 0;
CPQDIF_E_Collection * pcolOneChannelDefn;
CPQDIF_E_Collection * pcollSeriesDefns;
// Find the one channel defn we're looking for
pcolOneChannelDefn = GetOneChannelDefn( idxChannelDefn );
if( pcolOneChannelDefn )
{
// Is this the right tag?
const char * pname;
pname = theInfo.GetNameOfTag( pcolOneChannelDefn->GetTag() );
// Find the series defns for this channel defn
pcollSeriesDefns = GetSeriesDefns( pcolOneChannelDefn );
if( pcollSeriesDefns )
{
// Get the count!
count = pcollSeriesDefns->GetCount();
}
}
return count;
}
bool CPQDIF_R_DataSource::GetChannelDefnInfo
(
long idxChannelDefn,
string& name,
UINT4& idPhase,
GUID& idQuantityType,
UINT4& idQuantityMeasured
)
{
bool status = FALSE;
CPQDIF_E_Collection * pcolOneChannelDefn;
// Elements we need
CPQDIF_E_Vector * pvecName;
CPQDIF_E_Scalar * pscPhaseID;
CPQDIF_E_Scalar * pscQuantityID;
// Init
name = "";
idPhase = ID_PHASE_NONE; // default
idQuantityType = ID_QT_WAVEFORM; // default
idQuantityMeasured = ID_QM_NONE; // default
// Find the one channel defn we're looking for
pcolOneChannelDefn = GetOneChannelDefn( idxChannelDefn );
if( pcolOneChannelDefn )
{
// Is this the right tag?
const char * pname;
pname = theInfo.GetNameOfTag( pcolOneChannelDefn->GetTag() );
pvecName = FindVectorInCollection( pcolOneChannelDefn, tagChannelName ); // optional
if( pvecName )
{
pvecName->GetValues( name );
}
pscPhaseID = FindScalarInCollection( pcolOneChannelDefn, tagPhaseID );
if( pscPhaseID )
{
// Required; check the return value
status = pscPhaseID->GetValueUINT4( idPhase );
}
pscQuantityID = FindScalarInCollection( pcolOneChannelDefn, tagQuantityTypeID );
if( status && pscQuantityID )
{
// Required; check the return value
status = pscQuantityID->GetValueGUID( idQuantityType );
}
pscQuantityID = FindScalarInCollection( pcolOneChannelDefn, tagQuantityMeasuredID );
if( status && pscQuantityID )
{
// Required; check the return value
status = pscQuantityID->GetValueUINT4( idQuantityMeasured );
}
}
return status;
}
bool CPQDIF_R_DataSource::GetChannelPrimarySeries
(
long idxChannelDefn,
long& idxPrimarySeries
)
{
bool status = FALSE;
CPQDIF_E_Collection * pcolOneChannelDefn;
// Elements we need
CPQDIF_E_Scalar * psc;
UINT4 value;
// Find the one channel defn we're looking for
pcolOneChannelDefn = GetOneChannelDefn( idxChannelDefn );
if( pcolOneChannelDefn )
{
psc = FindScalarInCollection( pcolOneChannelDefn, tagPrimarySeriesIdx );
if( psc )
{
// Required; check the return value
status = psc->GetValueUINT4( value );
if( status )
idxPrimarySeries = (long) value;
}
}
return status;
}
bool CPQDIF_R_DataSource::GetSeriesDefnInfo
(
long idxChannelDefn,
long idxSeriesDefn,
UINT4& idQuantityUnits,
GUID& idValueType,
GUID& idQuantityCharacteristic,
UINT4& idStorageMethod
)
{
bool status = FALSE;
CPQDIF_E_Collection * pcolOneSeriesDefn;
CPQDIF_E_Scalar * pscalar;
// Init
idQuantityUnits = ID_QU_NONE;
idValueType = ID_SERIES_VALUE_TYPE_VAL;
idStorageMethod = ID_SERIES_METHOD_VALUES;
// Find the one channel defn we're looking for
pcolOneSeriesDefn = GetOneSeriesDefn( idxChannelDefn, idxSeriesDefn );
if( pcolOneSeriesDefn )
{
// Is this the right tag?
const char * pname;
pname = theInfo.GetNameOfTag( pcolOneSeriesDefn->GetTag() );
// These are all required; check the return values
status = TRUE;
pscalar = FindScalarInCollection( pcolOneSeriesDefn, tagQuantityUnitsID );
if( status && pscalar )
{
status = pscalar->GetValueUINT4( idQuantityUnits );
}
pscalar = FindScalarInCollection( pcolOneSeriesDefn, tagValueTypeID );
if( status && pscalar )
{
status = pscalar->GetValueGUID( idValueType );
}
pscalar = FindScalarInCollection( pcolOneSeriesDefn, tagQuantityCharacteristicID );
if( status && pscalar )
{
status = pscalar->GetValueGUID( idQuantityCharacteristic );
}
pscalar = FindScalarInCollection( pcolOneSeriesDefn, tagStorageMethodID );
if( status && pscalar )
{
status = pscalar->GetValueUINT4( idStorageMethod );
}
}
return status;
}
// Protected stuff
CPQDIF_E_Collection * CPQDIF_R_DataSource::GetChannelDefns( void )
{
CPQDIF_E_Collection * pcollDefns = NULL;
// Create the collection if it does not yet exist.
if( m_pcollMain )
{
pcollDefns = FindCollectionInCollection( m_pcollMain, tagChannelDefns );
if( !pcollDefns )
{
pcollDefns = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollDefns )
{
pcollDefns->SetTag( tagChannelDefns );
m_pcollMain->Add( pcollDefns );
}
}
}
return pcollDefns;
}
CPQDIF_E_Collection * CPQDIF_R_DataSource::GetOneChannelDefn
(
long idxChannelDefn
)
{
CPQDIF_E_Collection * pcolReturn = NULL;
CPQDIF_E_Collection * pcolInstances = GetChannelDefns();
CPQDIF_Element * pel;
if( pcolInstances )
{
pel = pcolInstances->GetElement( idxChannelDefn );
if( pel )
{
if( pel->GetElementType() == ID_ELEMENT_TYPE_COLLECTION
&& PQDIF_IsEqualGUID( pel->GetTag(), tagOneChannelDefn ) )
{
pcolReturn = (CPQDIF_E_Collection *) pel;
}
}
}
return pcolReturn;
}
CPQDIF_E_Collection * CPQDIF_R_DataSource::GetSeriesDefns
(
CPQDIF_E_Collection * pcolOneChannelDefn
)
{
return FindCollectionInCollection( pcolOneChannelDefn, tagSeriesDefns );
}
CPQDIF_E_Collection * CPQDIF_R_DataSource::GetOneSeriesDefn
(
CPQDIF_E_Collection * pcolOneChannelDefn,
long idxSeriesDefn
)
{
CPQDIF_E_Collection * pcolReturn = NULL;
CPQDIF_E_Collection * pcolSeriesDefns = NULL;
CPQDIF_Element * pel;
if( pcolOneChannelDefn )
{
// Grab the series defns collection for this channels defn.
pcolSeriesDefns = GetSeriesDefns( pcolOneChannelDefn );
if( pcolSeriesDefns )
{
// Is this the right tag?
const char * pname;
pname = theInfo.GetNameOfTag( pcolSeriesDefns->GetTag() );
// Find the specific series defn
pel = pcolSeriesDefns->GetElement( idxSeriesDefn );
if( pel )
{
pname = theInfo.GetNameOfTag( pel->GetTag() );
if( pel->GetElementType() == ID_ELEMENT_TYPE_COLLECTION
&& PQDIF_IsEqualGUID( pel->GetTag(), tagOneSeriesDefn ) )
{
// Return it!
pcolReturn = (CPQDIF_E_Collection *) pel;
}
}
}
}
return pcolReturn;
}
CPQDIF_E_Collection * CPQDIF_R_DataSource::GetOneSeriesDefn
(
long idxChannelDefn,
long idxSeriesDefn
)
{
CPQDIF_E_Collection * pcolReturn = NULL;
CPQDIF_E_Collection * pcolOneChannel = NULL;
pcolOneChannel = GetOneChannelDefn( idxChannelDefn );
if( pcolOneChannel )
{
pcolReturn = GetOneSeriesDefn( pcolOneChannel, idxSeriesDefn );
}
return pcolReturn;
}
long CPQDIF_R_DataSource::AddChannelDefn
(
const char * name,
UINT4 idPhase,
const GUID& idQuantityType
)
{
long idxNew = -1;
CPQDIF_E_Collection * pcollDefns;
CPQDIF_E_Collection * pcollOne;
CPQDIF_E_Collection * pcollSeriesDefns;
pcollDefns = GetChannelDefns();
if( pcollDefns )
{
// Get the new index
idxNew = GetCountChannelDefns();
// Create the new channel def'n
pcollOne = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollOne )
{
pcollOne->SetTag( tagOneChannelDefn );
// Stuff in the information...
pcollOne->SetVectorString( tagChannelName, name );
pcollOne->SetScalarUINT4( tagPhaseID, idPhase );
pcollOne->SetScalarGUID( tagQuantityTypeID, idQuantityType );
// Also add an empty collection for the series definitions
pcollSeriesDefns = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollSeriesDefns )
{
pcollSeriesDefns->SetTag( tagSeriesDefns );
pcollOne->Add( pcollSeriesDefns );
}
}
// Add it!
pcollDefns->Add( pcollOne );
}
return idxNew;
}
long CPQDIF_R_DataSource::AddChannelDefn2
(
const char * name,
UINT4 idPhase,
UINT4 idQM,
const GUID& idQuantityType
)
{
long idxNew = -1;
CPQDIF_E_Collection * pcollDefns;
CPQDIF_E_Collection * pcollOne;
CPQDIF_E_Collection * pcollSeriesDefns;
pcollDefns = GetChannelDefns();
if( pcollDefns )
{
// Get the new index
idxNew = GetCountChannelDefns();
// Create the new channel def'n
pcollOne = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollOne )
{
pcollOne->SetTag( tagOneChannelDefn );
// Stuff in the information...
pcollOne->SetVectorString( tagChannelName, name );
pcollOne->SetScalarUINT4( tagPhaseID, idPhase );
pcollOne->SetScalarUINT4( tagQuantityMeasuredID, idQM );
pcollOne->SetScalarGUID( tagQuantityTypeID, idQuantityType );
// Also add an empty collection for the series definitions
pcollSeriesDefns = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollSeriesDefns )
{
pcollSeriesDefns->SetTag( tagSeriesDefns );
pcollOne->Add( pcollSeriesDefns );
}
}
// Add it!
pcollDefns->Add( pcollOne );
}
return idxNew;
}
long CPQDIF_R_DataSource::AddSeriesDefn
(
long idxChannelDefn,
UINT4 idQuantityUnits,
const GUID idValueType,
UINT4 idStorageMethod
)
{
long idxNew = -1;
CPQDIF_E_Collection * pcolOneChannelDefn;
CPQDIF_E_Collection * pcollSeriesDefns;
CPQDIF_E_Collection * pcollOne;
// Find the one channel defn we're looking for
pcolOneChannelDefn = GetOneChannelDefn( idxChannelDefn );
if( pcolOneChannelDefn )
{
#ifdef _DEBUG
// Is this the right tag?
const char * pname;
pname = theInfo.GetNameOfTag( pcolOneChannelDefn->GetTag() );
#endif
// Find the series defns for this channel defn
pcollSeriesDefns = GetSeriesDefns( pcolOneChannelDefn );
if( pcollSeriesDefns )
{
// Get the new index
idxNew = GetCountSeriesDefns( idxChannelDefn );
// Create the new series def'n
pcollOne = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
pcollOne->SetTag( tagOneSeriesDefn );
// Stuff in the information...
pcollOne->SetScalarUINT4( tagQuantityUnitsID, idQuantityUnits );
pcollOne->SetScalarGUID( tagValueTypeID, idValueType );
pcollOne->SetScalarUINT4( tagStorageMethodID, idStorageMethod );
// Add it!
pcollSeriesDefns->Add( pcollOne );
}
}
return idxNew;
}
long CPQDIF_R_DataSource::AddSeriesDefn2
(
long idxChannelDefn,
UINT4 idQuantityUnits,
const GUID idValueType,
const GUID idCharacteristicType,
UINT4 idStorageMethod
)
{
long idxNew = -1;
CPQDIF_E_Collection * pcolOneChannelDefn;
CPQDIF_E_Collection * pcollSeriesDefns;
CPQDIF_E_Collection * pcollOne;
// Find the one channel defn we're looking for
pcolOneChannelDefn = GetOneChannelDefn( idxChannelDefn );
if( pcolOneChannelDefn )
{
#ifdef _DEBUG
// Is this the right tag?
const char * pname;
pname = theInfo.GetNameOfTag( pcolOneChannelDefn->GetTag() );
#endif
// Find the series defns for this channel defn
pcollSeriesDefns = GetSeriesDefns( pcolOneChannelDefn );
if( pcollSeriesDefns )
{
// Get the new index
idxNew = GetCountSeriesDefns( idxChannelDefn );
// Create the new series def'n
pcollOne = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
pcollOne->SetTag( tagOneSeriesDefn );
// Stuff in the information...
pcollOne->SetScalarUINT4( tagQuantityUnitsID, idQuantityUnits );
pcollOne->SetScalarGUID( tagQuantityCharacteristicID, idCharacteristicType );
pcollOne->SetScalarGUID( tagValueTypeID, idValueType );
pcollOne->SetScalarUINT4( tagStorageMethodID, idStorageMethod );
// Add it!
pcollSeriesDefns->Add( pcollOne );
}
}
return idxNew;
}
bool CPQDIF_R_DataSource::GetSeriesDefnNominal
(
long idxChannelDefn,
long idxSeriesDefn,
double & dNominal
)
{
bool status = false;
CPQDIF_E_Collection * pcolOneSeriesDefn;
CPQDIF_E_Scalar * pscalar;
// Initialize
dNominal = -1.0;
// Find the one channel defn we're looking for
pcolOneSeriesDefn = GetOneSeriesDefn( idxChannelDefn, idxSeriesDefn );
if( pcolOneSeriesDefn )
{
// Is this the right tag?
//
// Rob does this call over the place but does not
// do anything with the result. Why is it here? - EWG
//
// const char * pname;
// pname = theInfo.GetNameOfTag( pcolOneSeriesDefn->GetTag() );
// check the return values
status = true;
pscalar = FindScalarInCollection( pcolOneSeriesDefn, tagSeriesNominalQuantity );
if( status && pscalar )
{
status = pscalar->GetValueREAL8( dNominal );
}
}
return status;
}
bool CPQDIF_R_DataSource::GetSeriesDefnPrecisionAndResolution
(
long idxChannel,
long idxSeries,
UINT4 & uPrecision,
double & dResolution
)
{
CPQDIF_E_Collection * pcolOneSeriesDefn;
CPQDIF_E_Scalar * pscalar;
bool status = false;
// Initialize
uPrecision = -1;
dResolution = 0.0;
// Find the one channel defn we're looking for
pcolOneSeriesDefn = GetOneSeriesDefn( idxChannel, idxSeries );
if( pcolOneSeriesDefn )
{
// check the return values
status = true;
pscalar = FindScalarInCollection( pcolOneSeriesDefn, tagQuantitySignificantDigitsID );
if( status && pscalar )
{
status = pscalar->GetValueUINT4( uPrecision );
}
pscalar = FindScalarInCollection( pcolOneSeriesDefn, tagQuantityResolutionID );
if( pscalar )
{
pscalar->GetValueREAL8( dResolution );
}
}
return status;
}
bool CPQDIF_R_DataSource::SetSeriesDefnNominal
(
long idxChannelDefn,
long idxSeriesDefn,
double dNominal
)
{
bool status = false;
CPQDIF_E_Collection * pcolOneSeriesDefn;
CPQDIF_E_Scalar * pscalar;
// Find the one channel defn we're looking for
pcolOneSeriesDefn = GetOneSeriesDefn( idxChannelDefn, idxSeriesDefn );
if( pcolOneSeriesDefn )
{
// Is this the right tag?
//
// Rob does this call over the place but does not
// do anything with the result. Why is it here? - EWG
//
// const char * pname;
// pname = theInfo.GetNameOfTag( pcolOneSeriesDefn->GetTag() );
status = true;
//
//
// See if scalar already present
//
pscalar = FindScalarInCollection( pcolOneSeriesDefn, tagSeriesNominalQuantity );
if( pscalar )
{
//
//
// Is there so set new value
//
status = pscalar->SetValueREAL8( dNominal );
}
else
{
//
//
// Is not there so add scalar
//
pscalar = (CPQDIF_E_Scalar *) theFactory.NewElement( ID_ELEMENT_TYPE_SCALAR );
if( pscalar )
{
pscalar->SetTag( tagSeriesNominalQuantity );
status = pscalar->SetValueREAL8( dNominal );
pcolOneSeriesDefn->Add( pscalar );
}
}
#ifdef zap
//
//
// The following line does the same thing as the several
// lines above but without error checking.
//
// The third parameter allows replacement of tag
// value if tag already present. If tag not present,
// it is added and the value set.
// The
//
pcolOneSeriesDefn->SetScalarREAL8( tagSeriesNominalQuantity, dNominal, true);
#endif
}
return status;
}
bool CPQDIF_R_DataSource::SetSeriesDefnPrefix
(
long idxChannelDefn,
long idxSeriesDefn,
long idPrefix
)
{
bool status = false;
// Find the one channel defn we're looking for
CPQDIF_E_Collection * pcolOneSeriesDefn = GetOneSeriesDefn( idxChannelDefn, idxSeriesDefn );
if( pcolOneSeriesDefn )
{
status = true;
//
//
// The third parameter allows replacement of tag
// value if tag already present. If tag not present,
// it is added and the value set.
// The
//
pcolOneSeriesDefn->SetScalarUINT4( tagHintGreekPrefixID, idPrefix, true);
}
return status;
}
bool CPQDIF_R_DataSource::SetSeriesDefnUnits
(
long idxChannelDefn,
long idxSeriesDefn,
long idUnits
)
{
bool status = false;
// Find the one channel defn we're looking for
CPQDIF_E_Collection * pcolOneSeriesDefn = GetOneSeriesDefn( idxChannelDefn, idxSeriesDefn );
if( pcolOneSeriesDefn )
{
status = true;
//
//
// The third parameter allows replacement of tag
// value if tag already present. If tag not present,
// it is added and the value set.
// The
//
pcolOneSeriesDefn->SetScalarUINT4( tagHintPreferredUnitsID, idUnits, true);
}
return status;
}
bool CPQDIF_R_DataSource::SetSeriesDefnDisplay
(
long idxChannelDefn,
long idxSeriesDefn,
long idDisplay
)
{
bool status = false;
// Find the one channel defn we're looking for
CPQDIF_E_Collection * pcolOneSeriesDefn = GetOneSeriesDefn( idxChannelDefn, idxSeriesDefn );
if( pcolOneSeriesDefn )
{
status = true;
//
//
// The third parameter allows replacement of tag
// value if tag already present. If tag not present,
// it is added and the value set.
// The
//
pcolOneSeriesDefn->SetScalarUINT4( tagHintDefaultDisplayID, idDisplay, true);
}
return status;
}
bool CPQDIF_R_DataSource::SetSeriesDefnDigits
(
long idxChannelDefn,
long idxSeriesDefn,
long idDigits
)
{
bool status = false;
// Find the one channel defn we're looking for
CPQDIF_E_Collection * pcolOneSeriesDefn = GetOneSeriesDefn( idxChannelDefn, idxSeriesDefn );
if( pcolOneSeriesDefn )
{
status = true;
//
//
// The third parameter allows replacement of tag
// value if tag already present. If tag not present,
// it is added and the value set.
// The
//
pcolOneSeriesDefn->SetScalarUINT4( tagQuantitySignificantDigitsID, idDigits, true);
}
return status;
}
bool CPQDIF_R_DataSource::SetSeriesDefnResolution
(
long idxChannelDefn,
long idxSeriesDefn,
double dRes
)
{
bool status = false;
// Find the one channel defn we're looking for
CPQDIF_E_Collection * pcolOneSeriesDefn = GetOneSeriesDefn( idxChannelDefn, idxSeriesDefn );
if( pcolOneSeriesDefn )
{
status = true;
//
//
// The third parameter allows replacement of tag
// value if tag already present. If tag not present,
// it is added and the value set.
// The
//
pcolOneSeriesDefn->SetScalarREAL8( tagQuantityResolutionID, dRes, true);
}
return status;
}
bool CPQDIF_R_DataSource::SettagEffective
(
const TIMESTAMPPQDIF& timeEffective
)
{
bool status = false;
CPQDIF_E_Scalar * psc;
CPQDIF_E_Vector * pvect;
// Init
if (m_pcollMain == NULL)
return false;
// First, find (or create) the trigger method
psc = FindOrCreateScalarInCollection(m_pcollMain,
tagEffective, ID_PHYS_TYPE_TIMESTAMPPQDIF);
// Set its value
if (psc)
{
status = psc->SetValueTimeStamp(timeEffective);
}
return status;
}

View File

@@ -0,0 +1,146 @@
// File name: $Workfile: rec_datasource.h $
// Last modified: $Modtime: 5/25/99 10:52a $
// Last modified by: $Author: Jack $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/rec_datasource.h $
// VCS revision: $Revision: 16 $
class CPQDIF_R_DataSource : public CPQDIF_R_General
{
public:
CPQDIF_R_DataSource();
//CPQDIF_R_DataSource( CPQDIFRecord& record );
virtual ~CPQDIF_R_DataSource();
// Operations
public:
// Attributes
public:
// Read functions
bool GetInfo
(
GUID& idDataSourceType,
GUID& idVendor,
GUID& idEquipment,
string& serialNumber,
string& version,
string& name,
string& owner,
string& location,
string& timeZone
);
long GetCountChannelDefns( void );
long GetCountSeriesDefns( int idxChannelDefn );
bool GetChannelDefnInfo
(
long idxChannelDefn,
string& name,
UINT4& idPhase,
GUID& idQuantityType,
UINT4& idQuantityMeasured
);
bool GetChannelPrimarySeries
(
long idxChannel,
long& idxPrimarySeries
);
bool GetSeriesDefnInfo
(
long idxChannelDefn,
long idxSeriesDefn,
UINT4& idQuantityUnits,
GUID& idValueType,
GUID& idQuantityCharacteristic,
UINT4& idStorageMethod
);
// Write functions
long AddChannelDefn
(
const char * name,
UINT4 idPhase,
const GUID& idQuantityType
);
long AddChannelDefn2
(
const char * name,
UINT4 idPhase,
UINT4 idQM,
const GUID& idQuantityType
);
long AddSeriesDefn
(
long idxChannelDefn,
UINT4 idQuantityUnits,
const GUID idValueType,
UINT4 idStorageMethod
);
long AddSeriesDefn2
(
long idxChannelDefn,
UINT4 idQuantityUnits,
const GUID idValueType,
const GUID idCharacteristicType,
UINT4 idStorageMethod
);
bool SetSeriesDefnNominal(long idxChannelDefn, long idxSeriesDefn, double dNominal);
bool GetSeriesDefnNominal(long idxChannelDefn, long idxSeriesDefn, double & dNominal);
bool GetSeriesDefnPrecisionAndResolution
(
long idxChannel,
long idxSeries,
UINT4 & uPrecision,
double & dResolution
);
bool SetSeriesDefnPrefix(long idxChannelDefn, long idxSeriesDefn, long idPrefix);
bool SetSeriesDefnDisplay(long idxChannelDefn, long idxSeriesDefn, long idDisplay);
bool SetSeriesDefnUnits(long idxChannelDefn, long idxSeriesDefn, long idUnits);
bool SetSeriesDefnResolution(long idxChannelDefn, long idxSeriesDefn, double dRes);
bool SetSeriesDefnDigits(long idxChannelDefn, long idxSeriesDefn, long idDigits);
bool SetEffective (const TIMESTAMPPQDIF& timeEffective)
{
return SetTimeInMainCollection(tagEffective, timeEffective);
}
bool GetEffective (TIMESTAMPPQDIF& timeEffective)
{
return GetTimeInMainCollection(tagEffective, timeEffective);
}
bool SettagEffective
(
const TIMESTAMPPQDIF& timeEffective
);
// Internal functions
public:
CPQDIF_E_Collection * GetChannelDefns( void );
CPQDIF_E_Collection * GetOneChannelDefn
(
long idxChannelDefn
);
CPQDIF_E_Collection * GetSeriesDefns
(
CPQDIF_E_Collection * pcolChannelDefns
);
CPQDIF_E_Collection * GetOneSeriesDefn
(
CPQDIF_E_Collection * pcolChannelSeriesDefns,
long idxSeriesDefn
);
CPQDIF_E_Collection * GetOneSeriesDefn
(
long idxChannelDefn,
long idxSeriesDefn
);
// Local data
private:
};

View File

@@ -0,0 +1,413 @@
/*
** CPQDIF_R_General class. The base class for a PQDIF record.
** --------------------------------------------------------------------------
**
** File name: $Workfile: rec_general.cpp $
** Last modified: $Modtime: 11/14/00 8:41a $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/rec_general.cpp $
** VCS revision: $Revision: 11 $
*/
#include "PQDIF_classes.h"
// Construction
// ============
CPQDIF_R_General::CPQDIF_R_General()
{
// Init header structure
memset( &m_headerRecord, 0, sizeof( m_headerRecord ) );
m_headerRecord.guidRecordSignature = guidRecordSignaturePQDIF;
m_headerRecord.tagRecordType = tagBlank;
m_headerRecord.sizeHeader = sizeof( m_headerRecord );
// sizeData;
// linkNextRecord;
// checksum;
// auiReserved[ 4 ];
m_posThisRecord = 0;
m_pcollMain = NULL; // Body not read
m_changed = false;
}
CPQDIF_R_General::~CPQDIF_R_General()
{
if( m_pcollMain )
delete m_pcollMain;
}
bool CPQDIF_R_General::ReadHeader( CPQDIF_StreamIO * pstream )
{
bool status = false;
BYTE * buffer = NULL;
int sizeActual;
int pos;
// Init header structure
memset( &m_headerRecord, 0, sizeof( m_headerRecord ) );
status = pstream->GetPos( pos );
if( status )
{
m_posThisRecord = (LINKABS4) pos;
buffer = pstream->ReadBlock( sizeof( m_headerRecord ), sizeActual );
//ASSERT( sizeActual == sizeof( m_headerRecord ) );
}
if( status && buffer)
{
m_headerRecord = *( (c_record_mainheader *) buffer );
// Validate the signature
if( !PQDIF_IsEqualGUID( m_headerRecord.guidRecordSignature, guidRecordSignaturePQDIF ) )
{
status = FALSE;
}
}
return status;
}
bool CPQDIF_R_General::ReadBody( CPQDIF_StreamIO * pstream )
{
bool status = false;
PQController controller;
// Have we already read it?
if( m_pcollMain )
{
status = true;
}
else
{
// Nope -- create the top-level collection
m_pcollMain = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
//ASSERT( m_pcollMain );
if( m_pcollMain )
{
// Link the collection to the record.
m_pcollMain->SetRecord( this );
// Attach the record tag to the main collection
m_pcollMain->SetTag( m_headerRecord.tagRecordType );
// Position us to the right place
status = pstream->SeekPos( m_posThisRecord + m_headerRecord.sizeHeader );
if( status )
{
int sizeActual;
BYTE * buffer;
buffer = pstream->ReadBlock( m_headerRecord.sizeData, sizeActual );
if( buffer && sizeActual > 0 )
{
// Do it!
controller.ParseRecord( buffer, sizeActual, m_pcollMain );
status = TRUE;
}
}
}
}
return status;
}
bool CPQDIF_R_General::WriteHeader( CPQDIF_StreamIO * pstream )
{
bool status = FALSE;
SIZE4 sizeActual;
// Just write the dern block out!
// Position us to the right place
status = pstream->SeekPos( m_posThisRecord );
status = pstream->BeginBlock();
if( status )
{
status = pstream->AppendBlock(
(BYTE *) &m_headerRecord,
sizeof( m_headerRecord ) );
status = pstream->WriteBlock( sizeActual );
}
return status;
}
bool CPQDIF_R_General::WriteBody( CPQDIF_StreamIO * pstream )
{
bool status = FALSE;
PQAlloc allocPQ;
long sizeTotal;
c_collection_element * aem;
// Use the allocPQ to write out the main collection
if( m_pcollMain )
{
long idx;
SIZE4 size;
// Prepare
pstream->ResetChecksum();
// Position us to the right place
status = pstream->SeekPos( m_posThisRecord + m_headerRecord.sizeHeader );
aem = allocPQ.addCollection( m_pcollMain->GetCount(), idx, size );
if( aem )
{
status = BufferUpCollection( pstream, allocPQ, m_pcollMain, aem );
if( status )
{
sizeTotal = allocPQ.WriteListToStream( pstream );
if( sizeTotal == 0 )
status = false;
else
{
// Update header with data
m_headerRecord.sizeData = sizeTotal;
m_headerRecord.linkNextRecord = m_posThisRecord + m_headerRecord.sizeHeader + m_headerRecord.sizeData;
m_headerRecord.checksum = pstream->GetChecksum();
}
}
}
}
return status;
}
bool CPQDIF_R_General::BufferUpCollection
(
CPQDIF_StreamIO * pstream,
PQAlloc& allocPQ,
CPQDIF_E_Collection * pcoll,
c_collection_element * aem
)
{
bool status = TRUE;
long idxElement;
long countElements = pcoll->GetCount();
CPQDIF_Element * pel;
c_collection_element * aemNew;
long typePhysical;
PQDIFValue value;
long idx;
SIZE4 size;
for( idxElement = 0; idxElement < countElements; idxElement++ )
{
pel = pcoll->GetElement( idxElement );
if( pel )
{
switch( pel->GetElementType() )
{
case ID_ELEMENT_TYPE_COLLECTION:
{
CPQDIF_E_Collection * pcollNext = (CPQDIF_E_Collection *) pel;
aemNew = allocPQ.addCollection(
pcollNext->GetCount(),
idx, size,
pel->GetTag(),
aem[ idxElement ] );
if( aemNew )
{
status = BufferUpCollection(
pstream,
allocPQ,
pcollNext,
aemNew );
}
}
break;
case ID_ELEMENT_TYPE_SCALAR :
{
CPQDIF_E_Scalar * pscalar = (CPQDIF_E_Scalar *) pel;
pscalar->GetValue( typePhysical, value );
status = allocPQ.addScalarValue(
typePhysical,
value,
idx, size,
pscalar->GetTag(),
aem[ idxElement ] );
}
break;
case ID_ELEMENT_TYPE_VECTOR :
{
CPQDIF_E_Vector * pvector = (CPQDIF_E_Vector *) pel;
long count;
pvector->GetCount( count );
typePhysical = pvector->GetPhysicalType();
status = allocPQ.addVectorValue(
typePhysical,
count,
pvector->GetRawData(),
idx, size,
pvector->GetTag(),
aem[ idxElement ] );
}
break;
default:
break;
}
}
}
return status;
}
bool CPQDIF_R_General::SetMainCollection( CPQDIF_E_Collection * collMain )
{
bool status = true;
// Clear out old collection?
if( m_pcollMain )
{
delete m_pcollMain;
m_pcollMain = NULL;
}
if( collMain )
{
m_pcollMain = collMain;
collMain->SetRecord( this );
}
return status;
}
bool CPQDIF_R_General::GetTimeInMainCollection (const GUID &tag, TIMESTAMPPQDIF& timeTime)
{
// Initialize
bool foundItem = false;
memset( &timeTime, 0, sizeof( timeTime ) );
//
//
// See if we can find the item
//
CPQDIF_E_Scalar * psc = FindScalarInCollection( m_pcollMain, tag );
if( psc )
{
foundItem = psc->GetValueTimeStamp( timeTime );
}
return foundItem;
}
bool CPQDIF_R_General::GetREAL8InMainCollection (const GUID &tag, REAL8 & dVal)
{
// Initialize
bool foundItem = false;
dVal = 0.0;
//
//
// See if we can find the item
//
CPQDIF_E_Scalar * psc = FindScalarInCollection( m_pcollMain, tag );
if( psc )
{
foundItem = psc->GetValueREAL8( dVal );
}
return foundItem;
}
bool CPQDIF_R_General::GetBOOL4InMainCollection (const GUID &tag, BOOL4 & bVal)
{
// Initialize
bool foundItem = false;
bVal = false;
//
//
// See if we can find the item
//
CPQDIF_E_Scalar * psc = FindScalarInCollection( m_pcollMain, tag );
if( psc )
{
bool val;
foundItem = psc->GetValueBOOL4( val );
bVal = val;
}
return foundItem;
}
bool CPQDIF_R_General::SetTimeInMainCollection (const GUID &tag, const TIMESTAMPPQDIF& timeTime)
{
bool status = false;
CPQDIF_E_Scalar * psc = FindOrCreateScalarInCollection( m_pcollMain,
tag, ID_PHYS_TYPE_TIMESTAMPPQDIF );
// Set value
PQDIFValue value;
if( psc )
{
value.ts = timeTime;
status = psc->SetValue( ID_PHYS_TYPE_TIMESTAMPPQDIF, value );
}
return status;
}
bool CPQDIF_R_General::SetREAL8InMainCollection (const GUID &tag, const REAL8 dVal)
{
bool status = false;
CPQDIF_E_Scalar * psc = FindOrCreateScalarInCollection( m_pcollMain,
tag, ID_PHYS_TYPE_REAL8 );
// Set value
PQDIFValue value;
if( psc )
{
value.real8 = dVal;
status = psc->SetValue( ID_PHYS_TYPE_REAL8, value );
}
return status;
}
bool CPQDIF_R_General::SetBOOL4InMainCollection (const GUID &tag, const BOOL4 bVal)
{
bool status = false;
CPQDIF_E_Scalar * psc = FindOrCreateScalarInCollection( m_pcollMain,
tag, ID_PHYS_TYPE_BOOLEAN4 );
// Set value
PQDIFValue value;
if( psc )
{
value.bool4 = bVal;
status = psc->SetValue( ID_PHYS_TYPE_BOOLEAN4, value );
}
return status;
}

View File

@@ -0,0 +1,138 @@
// File name: $Workfile: rec_general.h $
// Last modified: $Modtime: 11/13/00 3:54p $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/rec_general.h $
// VCS revision: $Revision: 7 $
// Forward-declare these classes
class CPQDIF_StreamIO;
class CPQDIF_E_Collection;
class CPQDIF_E_Scalar;
class CPQDIF_E_Vector;
class PQAlloc;
union PQDIFValue;
class CPQDIF_R_General : public CPQDIFRecord
{
// Subclasses are friends - need to fix?
friend class CPQDIF_R_Observation;
friend class CPQDIF_R_DataSource;
public:
CPQDIF_R_General();
virtual ~CPQDIF_R_General();
// Operations
public:
virtual bool ReadHeader( CPQDIF_StreamIO * pstream );
virtual bool ReadBody( CPQDIF_StreamIO * pstream );
virtual bool WriteHeader( CPQDIF_StreamIO * pstream );
virtual bool WriteBody( CPQDIF_StreamIO * pstream );
// Attributes
public:
virtual bool HeaderGetPos( LINKABS4& pos ) const
{
pos = m_posThisRecord;
return true;
}
virtual bool HeaderSetPos( LINKABS4 pos )
{
m_posThisRecord = pos;
return true;
}
virtual bool HeaderGetTag( GUID& tagRecord ) const
{
tagRecord = m_headerRecord.tagRecordType;
return true;
}
virtual bool HeaderSetTag( GUID tagRecord )
{
m_headerRecord.tagRecordType = tagRecord;
return true;
}
virtual bool HeaderGetSize( SIZE4& sizeHeader, SIZE4& sizeBody ) const
{
sizeHeader = m_headerRecord.sizeHeader;
sizeBody = m_headerRecord.sizeData ;
return true;
}
virtual bool HeaderSetSize( SIZE4 sizeHeader, SIZE4 sizeBody )
{
m_headerRecord.sizeHeader = sizeHeader;
m_headerRecord.sizeData = sizeBody ;
return true;
}
virtual bool HeaderGetChecksum( UINT& checksum ) const
{
checksum = m_headerRecord.checksum;
return true;
}
virtual bool HeaderSetChecksum( UINT checksum )
{
m_headerRecord.checksum = checksum;
return true;
}
virtual bool HeaderGetPosNextRecord( LINKABS4& pos ) const
{
pos = m_headerRecord.linkNextRecord;
return true;
}
virtual bool HeaderSetPosNextRecord( LINKABS4 pos )
{
m_headerRecord.linkNextRecord = pos;
return true;
}
virtual CPQDIF_E_Collection * GetMainCollection( void ) const
{
return m_pcollMain;
}
virtual bool SetMainCollection( CPQDIF_E_Collection * collMain );
virtual bool GetChanged( void )
{
return m_changed;
}
virtual void SetChanged( bool changed )
{
m_changed = changed;
}
bool SetTimeInMainCollection (const GUID &tag, const TIMESTAMPPQDIF & timeTime);
bool SetREAL8InMainCollection (const GUID &tag, const REAL8 dVal);
bool SetBOOL4InMainCollection (const GUID &tag, const BOOL4 bVal);
bool GetTimeInMainCollection (const GUID &tag, TIMESTAMPPQDIF & timeTime);
bool GetREAL8InMainCollection (const GUID &tag, REAL8 & dVal);
bool GetBOOL4InMainCollection (const GUID &tag, BOOL4 & bVal);
// Overrides
public:
// Implementation
protected:
bool BufferUpCollection
(
CPQDIF_StreamIO * pstream,
PQAlloc& allocator,
CPQDIF_E_Collection * pcoll,
c_collection_element * aem
);
// Member data
protected:
c_record_mainheader m_headerRecord;
LINKABS4 m_posThisRecord;
CPQDIF_E_Collection * m_pcollMain; // Main collection element
// (if NULL, record has not been read yet)
bool m_changed; // Record changed flag.
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,339 @@
// File name: $Workfile: rec_observ.h $
// Last modified: $Modtime: 2/22/00 11:01p $
// Last modified by: $Author: Jack $
//
// VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/rec_observ.h $
// VCS revision: $Revision: 17 $
class CPQDIF_R_Settings;
class CPQDIF_R_Observation : public CPQDIF_R_General
{
public:
CPQDIF_R_Observation();
CPQDIF_R_Observation( CPQDIFRecord& record );
virtual ~CPQDIF_R_Observation();
// Operations
public:
void SetDataSource
(
CPQDIF_R_DataSource * pds
)
{ m_pds = pds; }
void SetMonitorSettings
(
CPQDIF_R_Settings * psett
)
{ m_psett = psett; }
CPQDIF_R_Settings * GetMonitorSettings()
{
return m_psett;
}
long GetCountResolvedSeries
(
long idxChannel,
long idxSeries,
bool noShare = false
);
double * NewResolvedSeries
(
long idxChannel,
long idxSeries,
long& countPoints,
bool noShare = false // Set to true to prevent another level of shared series.
// (This could prevent infinitely recursive calls.)
);
BOOL GetSeriesBaseType
(
long idxChannel,
long idxSeries,
long& nSeriesBaseType
);
TIMESTAMPPQDIF * NewResolvedSeriesTimeStamp
(
long idxChannel,
long idxSeries,
long& countPoints,
bool noShare = false
);
// Attributes
public:
// Read functions
bool GetInfo
(
TIMESTAMPPQDIF& timeStart,
TIMESTAMPPQDIF& timeCreate,
string& name
);
long GetCountChannels( void );
long GetCountSeries( int idxChannel );
bool GetChannelInfo
(
long idxChannel,
string& name,
UINT4& idPhase,
GUID& idQuantityType,
UINT4& idQuantityMeasured
);
bool GetChannelPrimarySeries
(
long idxChannel,
long& idxPrimarySeries
);
#ifdef zap
bool GetChannelThresholds
(
long idxChannel,
UINT4& triggerTypeID,
REAL8& fullScale,
REAL8& noiseFloor,
REAL8& triggerLow,
REAL8& triggerHigh,
REAL8& triggerRate,
CPQDIF_E_Vector& triggerShapeParam // Array of [3]
);
#endif
bool GetSeriesInfo
(
long idxChannel,
long idxSeries,
UINT4& idQuantityUnits,
GUID& idQuantityCharacteristic,
GUID& idValueType
);
bool GetTriggerInfo
(
UINT4& idTriggerMethod,
CPQDIF_E_Vector ** pvectTriggerChanIdx,
TIMESTAMPPQDIF& timeTriggered
);
bool GetPqdsInfo
(
GUID& idDataSourceType, // GUID
GUID& idInstrumentType, // GUID
UINT4& codeLocation,
CPQDIF_E_Vector ** pvectCodesDisturbanceType // Array[ 3 ] of UINT4
);
bool GetSeriesBaseQuantity
(
long idxChannel,
long idxSeries,
double& value
);
bool GetSeriesScale
(
long idxChannel,
long idxSeries,
double& scale,
double& offset
);
bool GetSeriesDefnNominal
(
long idxChannel,
long idxSeries,
double & dNominal
);
bool GetSeriesDefnPrecisionAndResolution
(
long idxChannel,
long idxSeries,
UINT4 & uPrecision,
double & dResolution
);
CPQDIF_E_Vector * GetSeriesValueVector
(
long idxChannel,
long idxSeries
);
// Write functions
long AddChannel
(
long idxChannelDefn
);
long AddSeriesDouble
(
long idxChannel,
long countValues,
double * arValues
);
bool SetSeriesBaseQuantity
(
long idxChannel,
long idxSeries,
double value
);
bool SetSeriesScale
(
long idxChannel,
long idxSeries,
double scale,
double offset
);
long AddSeriesVector
(
long idxChannel,
CPQDIF_E_Vector * pvect
);
long AddSeriesShared
(
long idxChannel,
long idxChannelShared,
long idxSeriesShared
);
bool SetTriggerInfo
(
UINT4 idTriggerMethod,
long countTriggers,
const UINT4 * aidxTriggerChan,
const TIMESTAMPPQDIF& timeTriggered
);
bool SetTimeCreateAndTimeStart
(
const TIMESTAMPPQDIF& timeCreate,
const TIMESTAMPPQDIF& timeStart
);
#ifdef PQDIF_USE_COM
bool GetObservationExtendedData
(
GUID& gidTag,
VARIANT& value
);
bool GetChannelExtendedData
(
long idxChannel,
GUID& gidTag,
VARIANT& value
);
bool GetSeriesExtendedData
(
long idxChannel,
long idxSeries,
GUID& gidTag,
VARIANT& value
);
#endif
// Internal functions
public:
bool GetChannelDefnIdx
(
long idxChannel,
long& idxChannelDefn
);
CPQDIF_E_Collection * GetChannelInstances( void );
CPQDIF_E_Collection * GetOneChannel
(
long idxChannel
);
CPQDIF_E_Collection * GetSeriesInstances
(
CPQDIF_E_Collection * pcolChannel
);
CPQDIF_E_Collection * GetOneSeries
(
CPQDIF_E_Collection * pcolChannel,
long idxSeries
);
CPQDIF_E_Collection * GetOneSeries
(
long idxChannel,
long idxSeries
);
// OVERRIDES
// Operations
public:
virtual bool ReadHeader( CPQDIF_StreamIO * pstream )
{ return m_record->ReadHeader( pstream ); }
virtual bool ReadBody( CPQDIF_StreamIO * pstream )
{ return m_record->ReadBody( pstream ); }
virtual bool WriteHeader( CPQDIF_StreamIO * pstream )
{ return m_record->WriteHeader( pstream ); }
virtual bool WriteBody( CPQDIF_StreamIO * pstream )
{ return m_record->WriteBody( pstream ); }
// OVERRIDES
// Attributes
public:
virtual bool HeaderGetPos( LINKABS4& pos ) const
{ return m_record->HeaderGetPos( pos ); }
virtual bool HeaderSetPos( LINKABS4 pos )
{ return m_record->HeaderSetPos( pos ); }
virtual bool HeaderGetTag( GUID& tagRecord ) const
{ return m_record->HeaderGetTag( tagRecord ); }
virtual bool HeaderSetTag( GUID tagRecord )
{ return m_record->HeaderSetTag( tagRecord ); }
virtual bool HeaderGetSize( SIZE4& sizeHeader, SIZE4& sizeBody ) const
{ return m_record->HeaderGetSize( sizeHeader, sizeBody ); }
virtual bool HeaderSetSize( SIZE4 sizeHeader, SIZE4 sizeBody )
{ return m_record->HeaderSetSize( sizeHeader, sizeBody ); }
virtual bool HeaderGetChecksum( UINT& checksum ) const
{ return m_record->HeaderGetChecksum( checksum ); }
virtual bool HeaderSetChecksum( UINT checksum )
{ return m_record->HeaderSetChecksum( checksum ); }
virtual bool HeaderGetPosNextRecord( LINKABS4& pos ) const
{ return m_record->HeaderGetPosNextRecord( pos ); }
virtual bool HeaderSetPosNextRecord( LINKABS4 pos )
{ return m_record->HeaderSetPosNextRecord( pos ); }
virtual CPQDIF_E_Collection * GetMainCollection( void ) const
{ return m_record->GetMainCollection(); }
virtual bool SetMainCollection( CPQDIF_E_Collection * collMain )
{ return m_record->SetMainCollection( collMain ); }
virtual bool GetChanged( void )
{ return m_record->GetChanged(); }
virtual void SetChanged( bool changed )
{ m_record->SetChanged( changed ); }
// Private functions
private:
long _GenerateSeriesCount
(
UINT4 idStorageMethod,
CPQDIF_E_Vector * pvectSeriesArray
);
double * _GenerateSeriesData
(
int idxChannelDefn,
UINT4 idStorageMethod,
double rBaseValue,
double rScale,
double rOffset,
CPQDIF_E_Vector * pvectSeriesArray,
long& countPoints
);
bool _GenerateTimeStampArray
(
TIMESTAMPPQDIF * result,
double * seconds,
long countPoints
);
bool _GetCalibrationRatio
(
int idxChannelDefn,
double& rScale
);
// Local data
private:
// Reference to the data source which owns this observation.
CPQDIF_R_DataSource * m_pds;
// Reference to the monitor settings record (can be NULL)
CPQDIF_R_Settings * m_psett;
// Reference to the record which contains the observation data.
CPQDIF_R_General * m_record; // need to fix
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,291 @@
// File name: $Workfile: rec_settings.h $
// Last modified: $Modtime: 2/22/00 7:35p $
// Last modified by: $Author: Jack $
//
// VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/rec_settings.h $
// VCS revision: $Revision: 13 $
class CPQDIF_R_Settings : public CPQDIF_R_General
{
public:
CPQDIF_R_Settings() {}
virtual ~CPQDIF_R_Settings() ;
// Operations
public:
// Attributes
public:
// Read functions
bool GetInfo
(
TIMESTAMPPQDIF& timeEffective,
TIMESTAMPPQDIF& timeInstalled,
TIMESTAMPPQDIF& timeRemoved,
bool& useCal,
bool& useTrans
);
bool GetConnectionInfo
(
UINT4& connectionType
);
long GetCountChannels( void );
bool GetChannelInfo (long idxChannel, UINT4 & idxChannelDefn);
#ifdef zap
//
//
// Depricated function
//
bool GetChannelInfo
(
long idxChannel,
UINT4& idxChannelDefn,
UINT4& triggerTypeID,
REAL8& fullScale,
REAL8& noiseFloor,
REAL8& triggerLow,
REAL8& triggerHigh,
REAL8& triggerRate,
CPQDIF_E_Vector& triggerShapeParam // Array of [3]
);
#endif
bool GetChanTrans
(
long idxChannel,
UINT4& xdTransformerTypeID,
REAL8& xdSystemSideRatio,
REAL8& xdMonitorSideRatio,
CPQDIF_E_Vector& xdFrequencyResponse // Array [n]
);
bool GetChanCal
(
long idxChannel,
REAL8& calTimeSkew,
REAL8& calOffset,
REAL8& calRatio,
bool& calMustUseARCal,
CPQDIF_E_Vector& calApplied, // Array [n]
CPQDIF_E_Vector& calRecorded // Array [n]
);
// Write functions
bool SetInfo
(
const TIMESTAMPPQDIF& timeEffective,
const TIMESTAMPPQDIF& timeInstalled,
const TIMESTAMPPQDIF& timeRemoved,
bool useCal,
bool useTrans
);
bool SetConnectionInfo
(
const UINT4 connectionType
);
#ifdef zap
//
//
// Depricated function
//
long AddChannel
(
UINT4 idxChannelDefn,
UINT4 triggerTypeID,
REAL8 fullScale,
REAL8 noiseFloor,
REAL8 triggerLow,
REAL8 triggerHigh,
REAL8 triggerRate,
const CPQDIF_E_Vector * triggerShapeParam // Array of [3] ... or NULL
);
#endif
long AddChannel
(
UINT4 idxChannel
);
long AddChannel
(
UINT4 idxChannel,
UINT4 idTriggerType
);
bool SetChanTrans
(
UINT4 idxChannel,
UINT4 xdTransformerTypeID,
REAL8 xdSystemSideRatio,
REAL8 xdMonitorSideRatio,
const CPQDIF_E_Vector * xdFrequencyResponse // Array [n]... or NULL
);
bool SetChanCal
(
UINT4 idxChannel,
REAL8 calTimeSkew,
REAL8 calOffset,
REAL8 calRatio,
bool calMustUseARCal,
const CPQDIF_E_Vector * calApplied, // Array [n]... or NULL
const CPQDIF_E_Vector * calRecorded // Array [n]... or NULL
);
bool SetTriggerShapeParam
(
UINT4 idxChannelDefn,
const CPQDIF_E_Vector * triggerShapeParam // Array of [3] ... or NULL
);
bool SetChannelReal8(UINT4 idxChannel, GUID tag, REAL8 dVal);
bool SetTriggerLow(const UINT4 idxChannel, const REAL8 dVal)
{
return SetChannelReal8(idxChannel, tagTriggerLow, dVal);
}
bool SetTriggerHigh(const UINT4 idxChannel, const REAL8 dVal)
{
return SetChannelReal8(idxChannel, tagTriggerHigh, dVal);
}
bool SetTriggerRate(const UINT4 idxChannel, const REAL8 dVal)
{
return SetChannelReal8(idxChannel, tagTriggerRate, dVal);
}
bool SetFullScale(const UINT4 idxChannel, const REAL8 dVal)
{
return SetChannelReal8(idxChannel, tagFullScale, dVal);
}
bool SetNoiseFloor(const UINT4 idxChannel, const REAL8 dVal)
{
return SetChannelReal8(idxChannel, tagNoiseFloor, dVal);
}
bool SetEffective (const TIMESTAMPPQDIF& timeEffective)
{
return SetTimeInMainCollection(tagEffective, timeEffective);
}
bool SetInstalled (const TIMESTAMPPQDIF& timeInstalled)
{
return SetTimeInMainCollection(tagTimeInstalled, timeInstalled);
}
bool SetRemoved (const TIMESTAMPPQDIF& timeRemoved)
{
return SetTimeInMainCollection(tagTimeRemoved, timeRemoved);
}
bool SetNominalFrequency(const REAL8 dVal)
{
return SetREAL8InMainCollection(tagNominalFrequency, dVal);
}
bool SetUseCalibration(const BOOL4 bVal)
{
return SetBOOL4InMainCollection(tagUseCalibration, bVal);
}
bool SetUseTransducer(const BOOL4 bVal)
{
return SetBOOL4InMainCollection(tagUseTransducer, bVal);
}
bool SettagIsPCC(const BOOL4 bVal)
{
return SetBOOL4InMainCollection(tagIsPCC, bVal);
}
bool SetNominalVoltage(const UINT4 bVal)
{
return SetREAL8InMainCollection(tagNominalVoltage, bVal);
}
bool GetChannelReal8(UINT4 idxChannel, GUID tag, REAL8 &dVal);
bool GetTriggerLow(const UINT4 idxChannel, REAL8 &dVal)
{
return GetChannelReal8(idxChannel, tagTriggerLow, dVal);
}
bool GetTriggerHigh(const UINT4 idxChannel, REAL8 &dVal)
{
return GetChannelReal8(idxChannel, tagTriggerHigh, dVal);
}
bool GetTriggerRate(const UINT4 idxChannel, REAL8 &dVal)
{
return GetChannelReal8(idxChannel, tagTriggerRate, dVal);
}
bool GetFullScale(const UINT4 idxChannel, REAL8 &dVal)
{
return GetChannelReal8(idxChannel, tagFullScale, dVal);
}
bool GetNoiseFloor(const UINT4 idxChannel, REAL8 &dVal)
{
return GetChannelReal8(idxChannel, tagNoiseFloor, dVal);
}
bool GetEffective (TIMESTAMPPQDIF& timeEffective)
{
return GetTimeInMainCollection(tagEffective, timeEffective);
}
bool GetInstalled (TIMESTAMPPQDIF& timeInstalled)
{
return GetTimeInMainCollection(tagTimeInstalled, timeInstalled);
}
bool GetRemoved (TIMESTAMPPQDIF& timeRemoved)
{
return GetTimeInMainCollection(tagTimeRemoved, timeRemoved);
}
bool GetNominalFrequency(REAL8 &dVal)
{
return GetREAL8InMainCollection(tagNominalFrequency, dVal);
}
bool GetUseCalibration(BOOL4 &bVal)
{
return GetBOOL4InMainCollection(tagUseCalibration, bVal);
}
bool GetUseTransducer(BOOL4 &bVal)
{
return GetBOOL4InMainCollection(tagUseTransducer, bVal);
}
bool SettagEffectiveAndtagTimeInstalledAndtagTimeRemoved
(
const TIMESTAMPPQDIF& timeEffective,
const TIMESTAMPPQDIF& TimeInstalled,
const TIMESTAMPPQDIF& TimeRemoved
);
// Internal functions
public:
CPQDIF_E_Collection * GetChannelSettings( void );
CPQDIF_E_Collection * GetOneChannelSetting
(
long idxChannelDefn
);
// Local data
private:
// None
};

View File

@@ -0,0 +1,589 @@
/*
** PQAlloc class. A simple allocator class that understands all of the
** fundamental PQDIF physical types.
** --------------------------------------------------------------------------
**
** File name: $Workfile: ser_alloc.cpp $
** Last modified: $Modtime: 9/03/98 9:52a $
** Last modified by: $Author: Rob $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/ser_alloc.cpp $
** VCS revision: $Revision: 5 $
*/
#include "PQDIF_classes.h"
/*
**
** Private node structure
*/
struct MemNode
{
void * obj;
size_t siz;
MemNode * pPrev;
MemNode * pNext;
};
// Memory debug
const int sizeGuardBand = 8;
const DWORD dataGuardBand = 121458711L;
void PQAlloc::Reinitialize(long offset)
{
DestroyList();
Initialize();
idxOffset = offset;
}
void PQAlloc::Initialize()
{
// DebugPrint("Initialize PQAlloc\n");
bShowMessage = 0;
lMemTotal = 0;
idxOffset = 0;
pmemFirst = 0;
pmemLast = 0;
}
PQAlloc::PQAlloc()
{
// DebugPrint("Create PQAlloc\n");
Initialize();
}
PQAlloc::~PQAlloc()
{
DestroyList();
// DebugPrint("Destroy PQAlloc\n");
}
//static char szBuffer[80];
void *PQAlloc::allocate(size_t siz)
{
size_t siz_obj;
void *obj;
siz_obj = siz;
obj = calloc( 1, siz + sizeGuardBand );
// Fill guard band with special p
//
if( sizeGuardBand > 0 )
{
DWORD *pdw = (DWORD *)((char *)obj+siz);
*pdw = dataGuardBand;
}
// Link memory object into list
//
LinkIn( obj, siz_obj );
return obj;
}
void *PQAlloc::allocate(size_t siz, long &idx)
{
/*
**
** Return offset into file for this object
*/
idx = lMemTotal + idxOffset;
return allocate(siz);
}
c_collection_element * PQAlloc::addCollection
(
UINT4 count,
long & idx,
SIZE4& size
)
{
struct c_collection * pcoll = NULL;
struct c_collection_element * parrayElement = NULL;
size = sizeof( c_collection ) + ( count * sizeof( c_collection_element ) );
size = theInfo.padSizeTo4Bytes( size );
pcoll = (c_collection *) allocate( size, idx );
if( pcoll )
{
// Init the collection header
pcoll->count = count;
// Find the beginning of the array
parrayElement = ( c_collection_element * ) ( ( (char *) pcoll ) + sizeof ( *pcoll ) );
}
return parrayElement;
}
c_collection_element * PQAlloc::addCollection
(
UINT4 count,
long & idx,
SIZE4& size,
const GUID& tag,
c_collection_element& ce
)
{
struct c_collection_element * parrayElement = NULL;
parrayElement = addCollection( count, idx, size );
if( parrayElement )
{
// Set up the collection element properly
ce.tagElement = tag;
ce.typeElement = ID_ELEMENT_TYPE_COLLECTION;
ce.typePhysical = 0; // ???
ce.isEmbedded = FALSE;
ce.reserved = 0;
ce.link.linkElement = idx;
ce.link.sizeElement = size;
}
return parrayElement;
}
bool PQAlloc::addScalarValue
(
long typePhysical,
PQDIFValue value,
long & idx,
SIZE4& size,
const GUID& tag,
c_collection_element& ce
)
{
bool status = FALSE;
SIZE4 sizeValue;
BYTE * pdata;
// Init the element header
ce.tagElement = tag;
ce.typeElement = ID_ELEMENT_TYPE_SCALAR;
ce.typePhysical = (INT1) typePhysical;
ce.isEmbedded = FALSE;
ce.reserved = 0;
// Init
pdata = NULL;
sizeValue = theInfo.GetNumBytesOfType( typePhysical );
if( sizeValue <= sizeof( ce.valueEmbedded ) )
{
// This is less than 8 bytes -- no allocation necessary
// Thereforem, it IS embedded
ce.isEmbedded = TRUE;
size = 0; // No add'l space allocated
// Set up the collection element properly
pdata = (BYTE *)( ce.valueEmbedded );
}
else
{
// Not embedded; gotta allocate memory (be sure to pad it
// to 4 bytes).
size = theInfo.padSizeTo4Bytes( sizeValue );
pdata = (BYTE *) allocate( size, idx );
if( pdata )
{
// Set up the collection element properly
ce.link.linkElement = idx;
ce.link.sizeElement = size;
}
}
// If we have the pointer, convert the value itself
if( pdata )
{
convertValue( typePhysical, value, pdata );
status = TRUE;
}
return status;
}
bool PQAlloc::addVectorValue
(
long typePhysical,
long count,
//PQDIFValue ** values,
BYTE * values,
long & idx,
SIZE4& size,
const GUID & tag,
c_collection_element& ce
)
{
bool status = FALSE;
SIZE4 sizeValue;
//long idxValue;
struct c_vector * pvector = NULL;
BYTE * pdata = NULL;
// Init the element header
ce.tagElement = tag;
ce.typeElement = ID_ELEMENT_TYPE_VECTOR;
ce.typePhysical = (INT1) typePhysical;
ce.isEmbedded = FALSE;
ce.reserved = 0;
// Determine the size of the vector
sizeValue = theInfo.GetNumBytesOfType( typePhysical );
size = sizeof( c_vector ) + ( count * sizeValue );
size = theInfo.padSizeTo4Bytes( size );
// Allocate the vector
pvector = (c_vector *) allocate( size, idx );
if( pvector )
{
// Init the vector header
pvector->count = count;
// Copy over the string portion
pdata = (BYTE *) ( ( (BYTE *) pvector ) + sizeof( c_vector ) );
if( pdata )
{
// Convert all the values in the array...
memcpy( pdata, values, count * sizeValue );
//for( idxValue = 0; idxValue < count; idxValue++ )
//{
//convertValue( typePhysical, *( values[ idxValue ] ), pdata );
//pdata += sizeValue;
//}
// All values in array have been transferred...
ce.link.linkElement = idx;
ce.link.sizeElement = size;
status = TRUE;
}
} // if( pvector )
return status;
}
bool PQAlloc::convertValue
(
long typePhysical,
PQDIFValue value,
BYTE * pdata
)
{
bool status = TRUE;
switch( typePhysical )
{
case ID_PHYS_TYPE_BOOLEAN1:
*( (BOOL1 *) pdata ) = value.bool1;
break;
case ID_PHYS_TYPE_CHAR1:
*( (CHAR1 *) pdata ) = value.char1;
break;
case ID_PHYS_TYPE_INTEGER1:
*( (INT1 *) pdata ) = value.int1;
break;
case ID_PHYS_TYPE_UNS_INTEGER1:
*( (UINT1 *) pdata ) = value.uint1;
break;
case ID_PHYS_TYPE_BOOLEAN2:
*( (BOOL2 *) pdata ) = value.bool2;
break;
case ID_PHYS_TYPE_CHAR2:
*( (CHAR2 *) pdata ) = value.char2;
break;
case ID_PHYS_TYPE_INTEGER2:
*( (INT2 *) pdata ) = value.int2;
break;
case ID_PHYS_TYPE_UNS_INTEGER2:
*( (UINT2 *) pdata ) = value.uint2;
break;
case ID_PHYS_TYPE_BOOLEAN4:
*( (BOOL4 *) pdata ) = value.bool4;
break;
case ID_PHYS_TYPE_INTEGER4:
*( (INT4 *) pdata ) = value.int4;
break;
case ID_PHYS_TYPE_UNS_INTEGER4:
*( (UINT4 *) pdata ) = value.uint4;
break;
case ID_PHYS_TYPE_REAL4:
*( (REAL4 *) pdata ) = value.real4;
break;
case ID_PHYS_TYPE_REAL8:
*( (REAL8 *) pdata ) = value.real8;
break;
case ID_PHYS_TYPE_COMPLEX8:
*( (COMPLEX8 *) pdata ) = value.complex8;
break;
case ID_PHYS_TYPE_COMPLEX16:
*( (COMPLEX16 *) pdata ) = value.complex16;
break;
case ID_PHYS_TYPE_TIMESTAMPPQDIF:
*( (ts *) pdata ) = value.ts;
break;
case ID_PHYS_TYPE_GUID:
*( (GUID *) pdata ) = value.guid ;
break;
default:
status = FALSE;
break;
}
return status;
}
void PQAlloc::deallocate( void *obj )
{
LinkOut( obj );
free( obj );
}
void PQAlloc::LinkIn(void *obj, size_t siz)
{
MemNode *pNode;
/*
**
** Allocate a new node
*/
pNode = (MemNode *) calloc( 1, sizeof( MemNode ) );
pNode->obj = obj;
pNode->siz = siz;
pNode->pNext = 0;
/*
**
** Save position suitable for use as the file offset
*/
lMemTotal += siz;
idxFilePosition = lMemTotal + idxOffset;
/*
**
** Put in chain
*/
if ( pmemLast )
pmemLast->pNext = pNode;
else
pmemFirst = pNode;
pNode->pPrev = pmemLast;
pmemLast = pNode;
}
int PQAlloc::LinkOut( void *obj )
{
MemNode *pNode;
int rc = 0;
pNode = pmemFirst;
while (pNode)
{
if (obj == pNode->obj)
{
if (pNode->pPrev)
pNode->pPrev->pNext = pNode->pNext;
else
pmemFirst = pNode->pNext;
if (pNode->pNext)
pNode->pNext->pPrev = pNode->pPrev;
else
pmemLast = pNode->pPrev;
lMemTotal -= pNode->siz;
if( sizeGuardBand )
{
DWORD *pdw = (DWORD *)( (char *) obj+pNode->siz );
if( *pdw != dataGuardBand )
{
if (bShowMessage)
{
//DebugPrint("Corrupted memory guard - %lu\n", *pdw);
// if (pNode->pszText)
// DebugPrint("obj= %p, size= %u, sz= %s\n",
// pNode->obj, pNode->siz, pNode->pszText);
// else
// DebugPrint("obj= %p, size= %u, Unknown location\n",
// pNode->obj, pNode->siz);
}
}
}
// if (pNode->pszText)
// free(pNode->pszText);
free( pNode );
rc = TRUE;
break;
}
pNode = pNode->pNext;
}
return rc;
}
void PQAlloc::WalkList()
{
MemNode *pNode;
if (!bShowMessage)
return;
pNode = pmemFirst;
//if (pNode == NULL)
// DebugPrint("The memory list is empty.\n");
while (pNode)
{
// if (pNode->pszText)
// DebugPrint("obj= %p, size= %u, sz= %s\n",
// pNode->obj, pNode->siz, pNode->pszText);
// else
// DebugPrint("obj= %p, size= %u, Unknown location\n",
// pNode->obj, pNode->siz);
pNode = pNode->pNext;
}
}
long PQAlloc::WriteListToFile(FILE *pf)
{
MemNode *pNode;
pNode = pmemFirst;
//if (pNode == NULL)
// DebugPrint("The memory list is empty.\n");
while (pNode)
{
fwrite(pNode->obj, 1, pNode->siz, pf);
// if (pNode->pszText)
// DebugPrint("obj= %p, size= %u, sz= %s\n",
// pNode->obj, pNode->siz, pNode->pszText);
// else
// DebugPrint("obj= %p, size= %u, Unknown location\n",
// pNode->obj, pNode->siz);
pNode = pNode->pNext;
}
return idxFilePosition;
}
long PQAlloc::WriteListToStream( CPQDIF_StreamIO *pstrm )
{
MemNode * pNode;
int sizeActualTotal;
sizeActualTotal = 0;
pstrm->BeginBlock();
pNode = pmemFirst;
//if (pNode == NULL)
// DebugPrint("The memory list is empty.\n");
while (pNode)
{
pstrm->AppendBlock( (BYTE *) pNode->obj, pNode->siz );
// if (pNode->pszText)
// DebugPrint("obj= %p, size= %u, sz= %s\n",
// pNode->obj, pNode->siz, pNode->pszText);
// else
// DebugPrint("obj= %p, size= %u, Unknown location\n",
// pNode->obj, pNode->siz);
pNode = pNode->pNext;
}
pstrm->WriteBlock( sizeActualTotal );
return sizeActualTotal;
}
void PQAlloc::DestroyList()
{
MemNode *pNode;
MemNode *pNext;
pNode = pmemFirst;
while (pNode)
{
pNext = pNode->pNext;
if (pNode->obj)
free(pNode->obj);
free(pNode);
pNode = pNext;
}
}
//int cdecl DebugPrint (char *szFormat,...)
// {
// char szBuffer [255];
// va_list arg_ptr;
//
// va_start (arg_ptr, szFormat);
//
// vsprintf (szBuffer, szFormat, arg_ptr);
//
// //printf(szBuffer);
//
//#ifdef _DEBUG
// //DebugOutput( DBF_TRACE, szBuffer );
//#endif
//
// return (0);
// }
#ifndef NOAUXPRINT
//int cdecl AuxPrint (char *szFormat,...)
// {
// char szBuffer [255];
// va_list arg_ptr;
//
// va_start (arg_ptr, szFormat);
//
// vsprintf (szBuffer, szFormat, arg_ptr);
//
//// OutputDebugString(szBuffer);
//
// return (0);
// }
#endif

View File

@@ -0,0 +1,101 @@
// File name: $Workfile: ser_alloc.h $
// Last modified: $Modtime: 2/09/98 12:08p $
// Last modified by: $Author: Rob $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/ser_alloc.h $
// VCS revision: $Revision: 3 $
#ifndef PQALLOC_INC
#define PQALLOC_INC
//#define bool short
//#define DWORD unsigned long
//#define TRUE 1
//#define FALSE 0
struct MemNode;
class PQAlloc
{
private:
void LinkIn (void * obj, size_t siz);
int LinkOut(void * obj);
MemNode * pmemFirst;
MemNode * pmemLast;
protected:
public:
PQAlloc();
~PQAlloc();
void Initialize();
void Reinitialize(long offset = 0L);
bool bShowMessage;
long lMemTotal; // Total size of objects managed in allocator
long idxFilePosition; // next available position in pseudo file
long idxOffset; // Offset to be added to the idx
// parameter returned by allocate
// Used to allow resetting allocators
// but return correct file offset
void *allocate(size_t siz);
void *allocate(size_t siz, long &idx);
// Routines to add specific PQDIF elements
c_collection_element * addCollection
(
UINT4 count,
long & idx,
SIZE4& size
);
c_collection_element * addCollection
(
UINT4 count,
long & idx,
SIZE4& size,
const GUID& tag,
c_collection_element& ce
);
bool addScalarValue
(
long typePhysical,
PQDIFValue value,
long & idx,
SIZE4& size,
const GUID& tag,
c_collection_element& ce
);
bool addVectorValue
(
long typePhysical,
long count,
BYTE * values,
long & idx,
SIZE4& size,
const GUID & tag,
c_collection_element& ce
);
static bool convertValue
(
long typePhysical,
PQDIFValue value,
BYTE * pdata
);
void deallocate(void * obj);
long WriteListToFile(FILE *pf);
long WriteListToStream( CPQDIF_StreamIO *pf );
void WalkList();
void DestroyList();
};
//extern int cdecl AuxPrint (char *szFormat,...);
//extern int cdecl DebugPrint (char *szFormat,...);
#endif

View File

@@ -0,0 +1,178 @@
/*
** PQController class. This class is used to control the reconstitution
** of PQDIF element objects from a buffer where they have been archived.
** --------------------------------------------------------------------------
**
** File name: $Workfile: ser_cont_el.cpp $
** Last modified: $Modtime: 10/07/02 7:41a $
** Last modified by: $Author: Jack $
**
** VCS archive path: $Archive: /PQDIF/PQDcom/PQDcom4/pqdiflib/ser_cont_el.cpp $
** VCS revision: $Revision: 11 $
*/
#include "PQDIF_classes.h"
// Construction
// ============
PQController::PQController( void )
{
}
PQController::~PQController( void )
{
}
void PQController::ParseRecord
(
BYTE * buffer,
SIZE4 size,
CPQDIF_E_Collection * pcollMain
)
{
PQDIFIterator piter( this, buffer, size, 0, pcollMain );
piter.ParseCollection();
return;
}
CPQDIF_E_Collection * PQController::acceptCollection
(
CPQDIF_E_Collection * pcoll,
int /*index*/,
const GUID& tag
)
{
CPQDIF_E_Collection * pcollNew;
// Create the new collection object
pcollNew = (CPQDIF_E_Collection *) theFactory.NewElement( ID_ELEMENT_TYPE_COLLECTION );
if( pcollNew )
{
// Add it to the previous collection
pcollNew->SetTag( tag );
pcoll->Add( pcollNew );
}
return pcollNew;
}
CPQDIF_E_Scalar * PQController::acceptScalar
(
CPQDIF_E_Collection * pcoll,
int /*index*/,
const GUID& tag,
long typePhysical,
void * pdata
)
{
CPQDIF_E_Scalar * pel;
//ASSERT( pdata );
// Create new element
pel = (CPQDIF_E_Scalar *) theFactory.NewElement( ID_ELEMENT_TYPE_SCALAR );
//ASSERT( pel );
if( pel )
{
// Initialize it. If successful then ...
pel->SetTag( tag );
if( pel->SetValue( typePhysical, *(PQDIFValue *)pdata ) )
{
// Add it to the current collection
//ASSERT( pcoll );
pcoll->Add( pel );
}
else
{
delete pel;
pel = NULL;
}
}
return pel;
}
CPQDIF_E_Vector * PQController::acceptVector
(
CPQDIF_E_Collection * pcoll,
int index,
const GUID& tag,
long typePhysical,
c_vector * pvector,
void * pdata
)
{
SIZE4 sizeValue;
CPQDIF_E_Vector * pel = NULL;
// Validate parameters
//ASSERT( pvector );
//ASSERT( pdata );
// Init
sizeValue = theInfo.GetNumBytesOfType( typePhysical );
SIZE4 TotalSize = sizeValue * pvector->count;
if ((TotalSize > 0) && (TotalSize < 1000000))
{
// Create new element
pel = (CPQDIF_E_Vector *) theFactory.NewElement( ID_ELEMENT_TYPE_VECTOR );
//ASSERT( pel );
if( pel )
{
// Initialize it
pel->SetTag( tag );
pel->SetPhysicalType( typePhysical );
if( pel->SetCount( pvector->count ) )
{
memcpy( pel->GetRawData(), pdata, pvector->count * sizeValue );
// Add the element to the current collection
//ASSERT( pcoll );
pcoll->Add( pel );
}
else
{
delete pel;
pel = NULL;
}
}
}
return pel;
}
bool PQController::decodeValue
(
long typePhysical,
void * pdata,
PQDIFValue& value
)
{
bool status = false;
int iSize = theInfo.GetNumBytesOfType( typePhysical );
if( iSize > 0 )
{
memcpy( (void *)&value, pdata, iSize );
status = true;
}
return status;
}

View File

@@ -0,0 +1,62 @@
// File name: $Workfile: ser_cont_el.h $
// Last modified: $Modtime: 11/21/00 5:20p $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/ser_cont_el.h $
// VCS revision: $Revision: 5 $
class CPQDIF_E_Collection;
class PQController
{
public:
PQController();
virtual ~PQController();
virtual void ParseRecord
(
BYTE * buffer,
SIZE4 size,
CPQDIF_E_Collection * pcollMain
);
// Routines to add specific PQDIF elements
// If return value is TRUE, the Iterator object
// will continue iterating through the elements
// in the collection. If FALSE, the collection
// will be skipped.
virtual CPQDIF_E_Collection * acceptCollection
(
CPQDIF_E_Collection * pcoll,
int index,
const GUID& tag
);
virtual CPQDIF_E_Scalar * acceptScalar
(
CPQDIF_E_Collection * pcoll,
int index,
const GUID& tag,
long typePhysical,
void * pdata
);
virtual CPQDIF_E_Vector * acceptVector
(
CPQDIF_E_Collection * pcoll,
int index,
const GUID& tag,
long typePhysical,
c_vector * pvector,
void * pdata
);
static bool decodeValue
(
long typePhysical,
void * pdata,
PQDIFValue& value
);
protected:
};

View File

@@ -0,0 +1,177 @@
/*
** PQDIFIterator class. Implements iteration through a set of PQDIF elements
** (stored in a collection) in order to reconstitute them from a buffer.
** Used in conjunction with the PQController class.
** --------------------------------------------------------------------------
**
** File name: $Workfile: ser_iter_el.cpp $
** Last modified: $Modtime: 11/21/00 5:31p $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/ser_iter_el.cpp $
** VCS revision: $Revision: 8 $
*/
#include "PQDIF_classes.h"
// Construction
// ============
PQDIFIterator::PQDIFIterator
(
PQController * pcont,
BYTE * buffer,
SIZE4 size,
long pos,
CPQDIF_E_Collection * pcoll
)
{
m_pcont = pcont;
m_buffer = buffer;
m_size = size;
m_pos = pos;
m_pcoll = pcoll;
}
PQDIFIterator::~PQDIFIterator()
{
}
bool PQDIFIterator::ParseCollection( void )
{
INT4 idx;
bool accepted = false;
c_collection collection;
c_collection_element * pelement;
// Get collection header
collection = *( (c_collection*) ( m_buffer + m_pos ) );
m_pos += sizeof( collection );
//ASSERT( m_pos < m_size || ( m_pos == m_size && collection.count == 0 ) );
//ASSERT( m_pos >= 0 );
// For each element in the collection do ...
pelement = (c_collection_element *) ( m_buffer + m_pos );
for( idx = 0; idx < collection.count; idx++, pelement++ )
{
// See what type it is, and see if it can be accepted
switch( pelement->typeElement )
{
case ID_ELEMENT_TYPE_COLLECTION:
{
CPQDIF_E_Collection * pcoll = m_pcont->acceptCollection(
m_pcoll,
idx,
pelement->tagElement );
accepted = pcoll != NULL;
if( accepted )
{
// Seek to the link (to the container header)
m_pos = pelement->link.linkElement;
//ASSERT( m_pos < m_size );
//ASSERT( m_pos > 0 );
if( m_pos >= m_size || m_pos <= 0 )
{
goto PQITPC_Abort;
}
// Should be at the right file position for this collection
PQDIFIterator iter(
m_pcont,
m_buffer,
m_size,
m_pos,
pcoll );
// Recursively parse the new collection
accepted = iter.ParseCollection();
}
}
break;
case ID_ELEMENT_TYPE_SCALAR:
{
// Alloc & read data
BYTE * pdata;
if( pelement->isEmbedded )
{
// Pull the data from the embedded value
pdata = (BYTE *) pelement->valueEmbedded;
}
else
{
// Seek to the link
m_pos = pelement->link.linkElement;
//ASSERT( m_pos < m_size );
//ASSERT( m_pos > 0 );
if( m_pos >= m_size || m_pos < 0 )
{
goto PQITPC_Abort;
}
pdata = (BYTE *) ( m_buffer + m_pos );
}
// Accept data?
accepted = m_pcont->acceptScalar(
m_pcoll,
idx,
pelement->tagElement,
pelement->typePhysical,
(void *) pdata) != NULL;
}
break;
case ID_ELEMENT_TYPE_VECTOR:
{
// Seek to the link (to the vector header)
m_pos = pelement->link.linkElement;
//ASSERT( m_pos < m_size );
//ASSERT( m_pos > 0 );
if( m_pos >= m_size || m_pos < 0 )
{
goto PQITPC_Abort;
}
// Grab vector header
c_vector vector = *( (c_vector *) ( m_buffer + m_pos ) );
m_pos += sizeof( vector );
// It is possible that this points off the end,
// if vector.count == 0.
//ASSERT( m_pos < m_size || vector.count == 0 );
//ASSERT( m_pos > 0 );
// Grab pointer to data
BYTE * pdata = (BYTE *) ( m_buffer + m_pos );
// Accept data? (The acceptVector() function
// must be careful not to go off the end if
// vector.count == 0.
accepted = m_pcont->acceptVector(
m_pcoll,
idx,
pelement->tagElement,
pelement->typePhysical,
&vector,
(void *) pdata) != NULL;
}
break;
} // switch()
} // for ()
PQITPC_Abort:
return accepted;
}

View File

@@ -0,0 +1,41 @@
// File name: $Workfile: ser_iter_el.h $
// Last modified: $Modtime: 11/21/00 4:50p $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/ser_iter_el.h $
// VCS revision: $Revision: 3 $
class PQController;
class PQDIFIterator
{
public:
PQDIFIterator
(
PQController * pcont,
BYTE * buffer,
SIZE4 size,
long pos,
CPQDIF_E_Collection * pcoll
);
~PQDIFIterator();
bool ParseCollection( void );
protected:
// Who wants the results?
PQController * m_pcont;
// Keep track of the record body buffer
// and our position in it
BYTE * m_buffer;
long m_pos;
long m_size;
// Keep track of how far deep into the PQDIF record we are
CPQDIF_E_Collection * m_pcoll;
private:
};

View File

@@ -0,0 +1,146 @@
/*
** CPQDIF_StreamIO class. The base class for implementing "stream I/O" which
** works along with a CPQDIF_PersistController class to supports a specific
** persistence mechanism.
** --------------------------------------------------------------------------
**
** File name: $Workfile: str_base.cpp $
** Last modified: $Modtime: 9/21/00 9:09a $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/str_base.cpp $
** VCS revision: $Revision: 8 $
*/
#include "PQDIF_classes.h"
// Local constants
const long sizeDefaultGrowBy = 16*1024;
// Construction
// ============
CPQDIF_StreamIO::CPQDIF_StreamIO()
{
m_processor = NULL;
m_canWriteFull = false;
m_canWriteInc = false;
m_buffRead.SetSize( 0, sizeDefaultGrowBy );
m_posRead = 0;
m_buffWrite.SetSize( 0, sizeDefaultGrowBy );
m_posWrite = 0;
}
CPQDIF_StreamIO::~CPQDIF_StreamIO()
{
}
bool CPQDIF_StreamIO::ConnectProcessor( CPQDIF_StreamProcessor * proc )
{
m_processor = proc;
return TRUE;
}
long CPQDIF_StreamIO::GetChecksum( void )
{
return m_processor->GetChecksum();
}
void CPQDIF_StreamIO::ResetChecksum( void )
{
m_processor->ResetChecksum();
}
bool CPQDIF_StreamIO::ExecuteProcessorEncode( void )
{
bool status = false;
if( m_processor )
{
// Make sure we are connected to it
m_processor->ConnectStream( this );
status = m_processor->StreamEncode();
}
return status;
}
bool CPQDIF_StreamIO::ExecuteProcessorDecode( void )
{
bool status = false;
if( m_processor )
{
// Make sure we are connected to it
m_processor->ConnectStream( this );
status = m_processor->StreamDecode();
}
return status;
}
bool CPQDIF_StreamIO::ProcessRead( const BYTE * &buffer, long max, long& sizeActual )
{
buffer = m_buffRead.GetData() + m_posRead; // Adjust to current position
sizeActual = m_buffRead.GetSize() - m_posRead; // Get size minus current position
if( max > 0 && max > sizeActual )
sizeActual = max;
return sizeActual > 0;
}
bool CPQDIF_StreamIO::ProcessWriteReserve( BYTE * & buffer, long size )
{
buffer = NULL;
bool status = m_buffWrite.SetSize( m_posWrite + size );
if( status )
{
buffer = m_buffWrite.GetData() + m_posWrite;
}
return status;
}
bool CPQDIF_StreamIO::ProcessWriteRelease( long size )
{
bool status = m_buffWrite.SetSize( m_posWrite + size );
if( status )
m_posWrite += size;
return status;
}
bool CPQDIF_StreamIO::BeginBlock( void )
{
bool status = true;
// Clear buffers
m_buffRead.SetSize( 0, sizeDefaultGrowBy );
m_posRead = 0;
return status;
}
bool CPQDIF_StreamIO::AppendBlock( BYTE * buffer, long size )
{
bool status = true;
// Fill the read buffer
m_buffRead.Append( buffer, size );
return status;
}

View File

@@ -0,0 +1,79 @@
// File name: $Workfile: str_base.h $
// Last modified: $Modtime: 9/20/00 11:42a $
// Last modified by: $Author: Bill $
//
// VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/str_base.h $
// VCS revision: $Revision: 6 $
// External interfaces
class CPQDIF_StreamProcessor;
class CPQDIF_StreamIO
{
public:
CPQDIF_StreamIO();
virtual ~CPQDIF_StreamIO();
// Attributes
public:
// Operations
public:
virtual bool SeekPos( int pos ) = 0;
virtual bool GetPos( int& pos ) = 0;
virtual bool SeekEnd( void ) = 0;
virtual BYTE * ReadBlock( long size, int& actualSize ) = 0;
virtual bool CanWriteFull( void ) const { return m_canWriteFull; }
virtual bool CanWriteIncremental( void ) const { return m_canWriteInc; }
virtual bool BeginBlock( void );
virtual bool AppendBlock( BYTE * buffer, long size );
virtual bool WriteBlock( int &sizeActual ) = 0;
virtual void Flush( void ) {} // Optional (default behavior: nothing)
virtual bool ConnectProcessor( CPQDIF_StreamProcessor * proc );
virtual long GetChecksum( void );
virtual void ResetChecksum( void );
// Called by the processor
// =======================
// Dereferences data buffered in the stream for the processor to read.
// The number of bytes available is returned in sizeActual. If max is 0,
// the total remaining length of the input buffer is returned.
// Returns FALSE when at end of buffer, TRUE otherwise.
virtual bool ProcessRead ( const BYTE * &buffer, long max, long& sizeActual );
// Reserves storage in the stream for the processor to write
// data into.
virtual bool ProcessWriteReserve( BYTE * &buffer, long size );
// This function is set the actual size of the buffer reserved
// by preceeding ProceWriteReserve call.
virtual bool ProcessWriteRelease( long sizeActual );
// Implementation
protected:
virtual bool ExecuteProcessorEncode( void );
virtual bool ExecuteProcessorDecode( void );
// Member data
protected:
// This is connected to the object, but not owned by it.
CPQDIF_StreamProcessor * m_processor;
// These are owned by the stream object
bool m_canWriteFull;
bool m_canWriteInc;
CPQByteArray m_buffRead;
long m_sizeRead;
long m_posRead;
CPQByteArray m_buffWrite;
long m_sizeWrite;
long m_posWrite;
};

View File

@@ -0,0 +1,211 @@
/*
** CPQDIF_S_Chunk class. A stream I/O implementing which supports "chunks."
** This will allow a PQDIF file to be embedded in a database binary field,
** for example.
** --------------------------------------------------------------------------
**
** File name: $Workfile: str_chnk.cpp $
** Last modified: $Modtime: 10/11/01 12:48p $
** Last modified by: $Author: Tomm $
**
** VCS archive path: $Archive: /ElectrotekLibs/Borland/PQDIFlib/str_chnk.cpp $
** VCS revision: $Revision: 7 $
*/
#include "PQDIF_classes.h"
// Construction
// ============
CPQDIF_S_Chunk::CPQDIF_S_Chunk()
{
m_chunkRead = NULL;
m_sizeChunkRead = 0;
m_chunkWrite.SetSize( 0, 64 );
m_posChunk = 0;
}
CPQDIF_S_Chunk::~CPQDIF_S_Chunk()
{
// Nothing to delete
}
bool CPQDIF_S_Chunk::SetInput( BYTE * chunk, long size )
{
bool status = FALSE;
if( chunk && size > 0 )
{
m_chunkRead = chunk;
m_sizeChunkRead = size;
status = TRUE;
}
else
{
m_chunkRead = NULL;
m_sizeChunkRead = 0;
}
return status;
}
bool CPQDIF_S_Chunk::GetOutputSize( long& size )
{
bool status = FALSE;
size = m_chunkWrite.GetSize();
status = TRUE;
return status;
}
bool CPQDIF_S_Chunk::GetOutput( BYTE * chunk, long maxSize )
{
bool status = FALSE;
long sizeActual;
if( chunk && maxSize > 0 )
{
sizeActual = min( maxSize, (long) m_chunkWrite.GetSize() );
memcpy( chunk, (BYTE *) m_chunkWrite.GetData(), sizeActual );
status = TRUE;
}
return status;
}
bool CPQDIF_S_Chunk::SeekPos( int pos )
{
bool status = FALSE;
m_posChunk = pos;
status = TRUE;
return status;
}
bool CPQDIF_S_Chunk::SeekEnd( void )
{
bool status = FALSE;
// Are we in read mode?
if( m_chunkRead )
{
m_posChunk = m_sizeChunkRead;
status = TRUE;
}
else
{
// Nope, write mode.
m_posChunk = m_chunkWrite.GetSize();
status = TRUE;
}
return status;
}
bool CPQDIF_S_Chunk::GetPos( int& pos )
{
bool status = false;
pos = m_posChunk;
status = true;
return status;
}
BYTE * CPQDIF_S_Chunk::ReadBlock( long size, int& actualSize )
{
BYTE * buffRet = NULL;
long sizeAvailable;
long sizeRead;
bool status = FALSE;
// Init
sizeRead = 0;
// Clear buffers
m_buffRead.SetSize( 0 );
m_posRead = 0;
m_buffWrite.SetSize( 0 );
m_posWrite = 0;
// Do we have a valid chunk to read?
if( m_chunkRead && m_sizeChunkRead > 0 && m_posChunk >= 0 )
{
// Attempt to read the block
sizeAvailable = m_sizeChunkRead - m_posChunk;
if( sizeAvailable > size )
{
sizeRead = size;
}
else
{
sizeRead = sizeAvailable;
}
// Did we get anything?
// (If not, we are at the end of the chunk and will return NULL.)
if( sizeRead > 0 )
{
// Size the buffer first & then copy the block
m_buffRead.SetSize( sizeRead );
memcpy( m_buffRead.GetData(), m_chunkRead+m_posChunk, sizeRead );
// Increment past the part we just read.
m_posChunk += sizeRead;
// We got the block -- now decode it.
status = ExecuteProcessorDecode();
if( status )
{
// Pass back the decoded buffer
buffRet = m_buffWrite.GetData();
actualSize = (long) m_buffWrite.GetSize();
}
}
}
return buffRet;
}
bool CPQDIF_S_Chunk::WriteBlock( int &sizeActual )
{
bool status = FALSE;
BYTE * pdataChunk;
// Init
m_buffWrite.SetSize( 0 );
m_posWrite = 0;
sizeActual = 0;
// Encode the block
status = ExecuteProcessorEncode();
if( status )
{
// The write buffer should contain the output
sizeActual = m_buffWrite.GetSize();
if( sizeActual > 0 )
{
// Force the position to the end of the chunk...
// and resize the write chunk.
m_posChunk = m_chunkWrite.GetSize();
m_chunkWrite.SetSize( m_posChunk + sizeActual );
// Find where this block goes
pdataChunk = (BYTE *) m_buffWrite.GetData();
pdataChunk += m_posChunk;
// Copy over the block
memcpy( pdataChunk, (BYTE *) m_buffWrite.GetData(), sizeActual );
m_posChunk += sizeActual;
status = TRUE;
}
}
return status;
}

View File

@@ -0,0 +1,36 @@
class CPQDIF_S_Chunk : public CPQDIF_StreamIO
{
public:
CPQDIF_S_Chunk();
virtual ~CPQDIF_S_Chunk();
// Attributes
public:
// Operations
public:
bool SetInput( BYTE * chunk, long size );
bool GetOutputSize( long& size );
bool GetOutput( BYTE * chunk, long maxSize );
// Overridables
public:
virtual bool SeekPos( int pos );
virtual bool GetPos( int& pos );
virtual bool SeekEnd( void );
virtual BYTE * ReadBlock( long size, int& actualSize );
virtual bool WriteBlock( int &sizeActual );
// Implementation
protected:
BYTE * m_chunkRead;
long m_sizeChunkRead;
CPQByteArray m_chunkWrite;
long m_posChunk;
};

View File

@@ -0,0 +1,239 @@
/*
** CPQDIF_S_FlatFile class. A stream I/O implementing which supports the
** standard flat file. This is the normal persistence mechanism for PQDIF.
** --------------------------------------------------------------------------
**
** File name: $Workfile: str_flat.cpp $
** Last modified: $Modtime: 9/21/00 8:19a $
** Last modified by: $Author: Bill $
**
** VCS archive path: $Archive: /Hank/DMM/FirmWare/Level3/ObDatMgr/str_flat.cpp $
** VCS revision: $Revision: 7 $
*/
#include "PQDIF_classes.h"
// Construction
// ============
CPQDIF_S_FlatFile::CPQDIF_S_FlatFile()
{
m_pf = NULL;
}
CPQDIF_S_FlatFile::~CPQDIF_S_FlatFile()
{
if( m_pf )
{
fclose( m_pf );
}
}
bool CPQDIF_S_FlatFile::Open
(
const char * fname,
bool readOnly
)
{
bool status = FALSE;
const char * flagsOpen = "";
if( readOnly )
{
// Read-only
flagsOpen = "rb";
m_canWriteFull = FALSE;
m_canWriteInc = FALSE;
}
else
{
// Read/write
flagsOpen = "r+b";
m_canWriteFull = TRUE;
m_canWriteInc = TRUE;
}
if( !m_pf )
{
#ifdef WIN32
fopen_s(&m_pf,fname, flagsOpen);
#else
m_pf = fopen(fname, flagsOpen);
#endif // WIN32
if( m_pf )
status = TRUE;
}
return status;
}
bool CPQDIF_S_FlatFile::New( const char * fname )
{
bool status = FALSE;
// Init
m_canWriteFull = FALSE;
m_canWriteInc = FALSE;
if( !m_pf )
{
#ifdef WIN32
fopen_s(&m_pf,fname, "w+b");
#else
m_pf = fopen(fname, "w+b");
#endif // WIN32
if( m_pf )
{
m_canWriteFull = TRUE;
m_canWriteInc = TRUE;
status = TRUE;
}
}
return status;
}
bool CPQDIF_S_FlatFile::SeekPos( int pos )
{
bool status = FALSE;
if( m_pf )
{
int rc = fseek( m_pf, pos, SEEK_SET );
if( rc == 0 )
status = TRUE;
}
return status;
}
bool CPQDIF_S_FlatFile::SeekEnd( void )
{
bool status = FALSE;
if( m_pf )
{
int rc = fseek( m_pf, 0, SEEK_END );
if( rc == 0 )
status = TRUE;
}
return status;
}
bool CPQDIF_S_FlatFile::GetPos( int& pos )
{
bool status = FALSE;
if( m_pf )
{
//#ifdef WIN32
pos = ftell( m_pf );
//#else
// fpos_t position;
// fgetpos( m_pf, &position);
// pos = (long)position;
//#endif
status = TRUE;
}
return status;
}
BYTE * CPQDIF_S_FlatFile::ReadBlock( long size, int& actualSize )
{
BYTE * buffRet = NULL;
long sizeRead;
bool status = FALSE;
// Init
sizeRead = 0;
// Clear buffers
m_buffRead.SetSize( 0 );
m_posRead = 0;
m_buffWrite.SetSize( 0 );
m_posWrite = 0;
if( m_pf )
{
// End of file yet?
if( ! feof( m_pf ) )
{
// Nope, read a buffer full...
// Size the buffer first
m_buffRead.SetSize( size );
// Attempt to read the block
sizeRead = (long) fread( (BYTE*) m_buffRead.GetData(), 1, size, m_pf );
if( sizeRead > 0 )
{
// We got the block -- now decode it.
m_buffRead.SetSize( sizeRead );
status = ExecuteProcessorDecode();
if( status )
{
// Pass back the decoded buffer
buffRet = m_buffWrite.GetData();
actualSize = (long) m_buffWrite.GetSize();
}
}
}
}
return buffRet;
}
bool CPQDIF_S_FlatFile::WriteBlock( int &sizeActual )
{
bool status = FALSE;
long sizeWritten;
m_buffWrite.SetSize( 0 );
m_posWrite = 0;
sizeActual = 0;
if( m_pf )
{
// End of file yet?
if( ! feof( m_pf ) )
{
// Encode the block
status = ExecuteProcessorEncode();
if( status )
{
// The write buffer should contain the output
sizeActual = m_buffWrite.GetSize();
// Attempt to read the block
sizeWritten = (long) fwrite( (BYTE*) m_buffWrite.GetData(), 1, sizeActual, m_pf );
if( sizeWritten == sizeActual )
{
status = TRUE;
}
}
}
}
return status;
}
void CPQDIF_S_FlatFile::Flush( void )
{
if( m_pf )
{
fflush( m_pf );
}
}

View File

@@ -0,0 +1,38 @@
#include <stdio.h>
class CPQDIF_S_FlatFile : public CPQDIF_StreamIO
{
public:
CPQDIF_S_FlatFile();
virtual ~CPQDIF_S_FlatFile();
// Attributes
public:
// Operations
public:
bool Open
(
const char * fname,
bool readOnly
);
bool New( const char * fname );
bool Connect( FILE * pf ) { m_pf = pf; return true; }
FILE * GetFile( void ) { return m_pf; }
// Overridables
public:
virtual bool SeekPos( int pos );
virtual bool GetPos( int& pos );
virtual bool SeekEnd( void );
virtual BYTE * ReadBlock( long size, int& actualSize );
virtual bool WriteBlock( int &sizeActual );
virtual void Flush( void );
// Implementation
protected:
FILE * m_pf;
};

View File

@@ -0,0 +1,248 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-1998 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
/* @(#) $Id$ */
#ifndef _ZCONF_H
#define _ZCONF_H
/*
* If you *really* need a unique prefix for all types and library functions,
* compile with -DZ_PREFIX. The "standard" zlib should be compiled without it.
*/
#ifdef Z_PREFIX
# define deflateInit_ z_deflateInit_
# define deflate z_deflate
# define deflateEnd z_deflateEnd
# define inflateInit_ z_inflateInit_
# define inflate z_inflate
# define inflateEnd z_inflateEnd
# define deflateInit2_ z_deflateInit2_
# define deflateSetDictionary z_deflateSetDictionary
# define deflateCopy z_deflateCopy
# define deflateReset z_deflateReset
# define deflateParams z_deflateParams
# define inflateInit2_ z_inflateInit2_
# define inflateSetDictionary z_inflateSetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateReset z_inflateReset
# define compress z_compress
# define uncompress z_uncompress
# define adler32 z_adler32
# define crc32 z_crc32
# define get_crc_table z_get_crc_table
# define Byte z_Byte
# define uInt z_uInt
# define uLong z_uLong
# define Bytef z_Bytef
# define charf z_charf
# define intf z_intf
# define uIntf z_uIntf
# define uLongf z_uLongf
# define voidpf z_voidpf
# define voidp z_voidp
#endif
#if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
# define WIN32
#endif
#if defined(__GNUC__) || defined(WIN32) || defined(__386__) || defined(i386)
# ifndef __32BIT__
# define __32BIT__
# endif
#endif
#if defined(__MSDOS__) && !defined(MSDOS)
# define MSDOS
#endif
/*
* Compile with -DMAXSEG_64K if the alloc function cannot allocate more
* than 64k bytes at a time (needed on systems with 16-bit int).
*/
#if defined(MSDOS) && !defined(__32BIT__)
# define MAXSEG_64K
#endif
#ifdef MSDOS
# define UNALIGNED_OK
#endif
#if (defined(MSDOS) || defined(_WINDOWS) || defined(WIN32)) && !defined(STDC)
# define STDC
#endif
#if defined(__STDC__) || defined(__cplusplus) || defined(__OS2__)
# ifndef STDC
# define STDC
# endif
#endif
#ifndef STDC
# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
# define const
# endif
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__) || defined(applec) ||defined(THINK_C) ||defined(__SC__)
# define NO_DUMMY_DECL
#endif
/* Borland C incorrectly complains about missing returns: */
#if defined(__BORLANDC__)
# define NEED_DUMMY_RETURN
#endif
/* Maximum value for memLevel in deflateInit2 */
#ifndef MAX_MEM_LEVEL
# ifdef MAXSEG_64K
# define MAX_MEM_LEVEL 8
# else
# define MAX_MEM_LEVEL 9
# endif
#endif
/* Maximum value for windowBits in deflateInit2 and inflateInit2.
* WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
* created by gzip. (Files created by minigzip can still be extracted by
* gzip.)
*/
#ifndef MAX_WBITS
# define MAX_WBITS 15 /* 32K LZ77 window */
#endif
/* The memory requirements for deflate are (in bytes):
(1 << (windowBits+2)) + (1 << (memLevel+9))
that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
plus a few kilobytes for small objects. For example, if you want to reduce
the default memory requirements from 256K to 128K, compile with
make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
Of course this will generally degrade compression (there's no free lunch).
The memory requirements for inflate are (in bytes) 1 << windowBits
that is, 32K for windowBits=15 (default value) plus a few kilobytes
for small objects.
*/
/* Type declarations */
#ifndef OF /* function prototypes */
# ifdef STDC
# define OF(args) args
# else
# define OF(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
* to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
* just define FAR to be empty.
*/
#if (defined(M_I86SM) || defined(M_I86MM)) && !defined(__32BIT__)
/* MSC small or medium model */
# define SMALL_MEDIUM
# ifdef _MSC_VER
# define FAR __far
# else
# define FAR far
# endif
#endif
#if defined(__BORLANDC__) && (defined(__SMALL__) || defined(__MEDIUM__))
# ifndef __32BIT__
# define SMALL_MEDIUM
# define FAR __far
# endif
#endif
#ifndef FAR
# define FAR
#endif
typedef unsigned char Byte; /* 8 bits */
typedef unsigned int uInt; /* 16 bits or more */
typedef unsigned long uLong; /* 32 bits or more */
#if defined(__BORLANDC__) && defined(SMALL_MEDIUM)
/* Borland C/C++ ignores FAR inside typedef */
# define Bytef Byte FAR
#else
typedef Byte FAR Bytef;
#endif
typedef char FAR charf;
typedef int FAR intf;
typedef uInt FAR uIntf;
typedef uLong FAR uLongf;
#ifdef STDC
typedef void FAR *voidpf;
typedef void *voidp;
#else
typedef Byte FAR *voidpf;
typedef Byte *voidp;
#endif
#ifdef HAVE_UNISTD_H
# include <sys/types.h> /* for off_t */
# include <unistd.h> /* for SEEK_* and off_t */
# define z_off_t off_t
#endif
#ifndef SEEK_SET
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
#endif
#ifndef z_off_t
# define z_off_t long
#endif
/* Compile with -DZLIB_DLL for Windows DLL support */
#if (defined(_WINDOWS) || defined(WINDOWS)) && defined(ZLIB_DLL)
# undef FAR
# include <windows.h>
# define EXPORT WINAPI
# ifdef WIN32
# define EXPORTVA WINAPIV
# else
# define EXPORTVA FAR _cdecl _export
# endif
#else
# if defined (__BORLANDC__) && defined (_Windows) && defined (__DLL__)
# define EXPORT _export
# define EXPORTVA _export
# else
# define EXPORT
# define EXPORTVA
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */
#if defined(__MVS__)
# pragma map(deflateInit_,"DEIN")
# pragma map(deflateInit2_,"DEIN2")
# pragma map(deflateEnd,"DEEND")
# pragma map(inflateInit_,"ININ")
# pragma map(inflateInit2_,"ININ2")
# pragma map(inflateEnd,"INEND")
# pragma map(inflateSync,"INSY")
# pragma map(inflateSetDictionary,"INSEDI")
# pragma map(inflate_blocks,"INBL")
# pragma map(inflate_blocks_new,"INBLNE")
# pragma map(inflate_blocks_free,"INBLFR")
# pragma map(inflate_blocks_reset,"INBLRE")
# pragma map(inflate_codes_free,"INCOFR")
# pragma map(inflate_codes,"INCO")
# pragma map(inflate_fast,"INFA")
# pragma map(inflate_flush,"INFLU")
# pragma map(inflate_mask,"INMA")
# pragma map(inflate_set_dictionary,"INSEDI2")
# pragma map(inflate_copyright,"INCOPY")
# pragma map(inflate_trees_bits,"INTRBI")
# pragma map(inflate_trees_dynamic,"INTRDY")
# pragma map(inflate_trees_fixed,"INTRFI")
# pragma map(inflate_trees_free,"INTRFR")
#endif
#endif /* _ZCONF_H */

View File

@@ -0,0 +1,868 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.0.8, Jan 27th, 1998
Copyright (C) 1995-1998 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
Jean-loup Gailly Mark Adler
jloup@gzip.org madler@alumni.caltech.edu
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files ftp://ds.internic.net/rfc/rfc1950.txt
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
*/
#ifndef _ZLIB_H
#define _ZLIB_H
#ifdef __cplusplus
extern "C" {
#endif
#include "zconf.h"
#define ZLIB_VERSION "1.0.8"
/*
The 'zlib' compression library provides in-memory compression and
decompression functions, including integrity checks of the uncompressed
data. This version of the library supports only one compression method
(deflation) but other algorithms will be added later and will have the same
stream interface.
Compression can be done in a single step if the buffers are large
enough (for example if an input file is mmap'ed), or can be done by
repeated calls of the compression function. In the latter case, the
application must provide more input and/or consume the output
(providing more output space) before each call.
The library also supports reading and writing files in gzip (.gz) format
with an interface similar to that of stdio.
The library does not install any signal handler. The decoder checks
the consistency of the compressed data, so the library should never
crash even in case of corrupted input.
*/
typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
typedef void (*free_func) OF((voidpf opaque, voidpf address));
struct internal_state;
typedef struct z_stream_s {
Bytef *next_in; /* next input byte */
uInt avail_in; /* number of bytes available at next_in */
uLong total_in; /* total nb of input bytes read so far */
Bytef *next_out; /* next output byte should be put there */
uInt avail_out; /* remaining free space at next_out */
uLong total_out; /* total nb of bytes output so far */
char *msg; /* last error message, NULL if no error */
struct internal_state FAR *state; /* not visible by applications */
alloc_func zalloc; /* used to allocate the internal state */
free_func zfree; /* used to free the internal state */
voidpf opaque; /* private data object passed to zalloc and zfree */
int data_type; /* best guess about the data type: ascii or binary */
uLong adler; /* adler32 value of the uncompressed data */
uLong reserved; /* reserved for future use */
} z_stream;
typedef z_stream FAR *z_streamp;
/*
The application must update next_in and avail_in when avail_in has
dropped to zero. It must update next_out and avail_out when avail_out
has dropped to zero. The application must initialize zalloc, zfree and
opaque before calling the init function. All other fields are set by the
compression library and must not be updated by the application.
The opaque value provided by the application will be passed as the first
parameter for calls of zalloc and zfree. This can be useful for custom
memory management. The compression library attaches no meaning to the
opaque value.
zalloc must return Z_NULL if there is not enough memory for the object.
On 16-bit systems, the functions zalloc and zfree must be able to allocate
exactly 65536 bytes, but will not be required to allocate more than this
if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
pointers returned by zalloc for objects of exactly 65536 bytes *must*
have their offset normalized to zero. The default allocation function
provided by this library ensures this (see zutil.c). To reduce memory
requirements and avoid any allocation of 64K objects, at the expense of
compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
The fields total_in and total_out can be used for statistics or
progress reports. After compression, total_in holds the total size of
the uncompressed data and may be saved for use in the decompressor
(particularly if the decompressor wants to decompress everything in
a single step).
*/
/* constants */
#define Z_NO_FLUSH 0
#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
#define Z_SYNC_FLUSH 2
#define Z_FULL_FLUSH 3
#define Z_FINISH 4
/* Allowed flush values; see deflate() below for details */
#define Z_OK 0
#define Z_STREAM_END 1
#define Z_NEED_DICT 2
#define Z_ERRNO (-1)
#define Z_STREAM_ERROR (-2)
#define Z_DATA_ERROR (-3)
#define Z_MEM_ERROR (-4)
#define Z_BUF_ERROR (-5)
#define Z_VERSION_ERROR (-6)
/* Return codes for the compression/decompression functions. Negative
* values are errors, positive values are used for special but normal events.
*/
#define Z_NO_COMPRESSION 0
#define Z_BEST_SPEED 1
#define Z_BEST_COMPRESSION 9
#define Z_DEFAULT_COMPRESSION (-1)
/* compression levels */
#define Z_FILTERED 1
#define Z_HUFFMAN_ONLY 2
#define Z_DEFAULT_STRATEGY 0
/* compression strategy; see deflateInit2() below for details */
#define Z_BINARY 0
#define Z_ASCII 1
#define Z_UNKNOWN 2
/* Possible values of the data_type field */
#define Z_DEFLATED 8
/* The deflate compression method (the only one supported in this version) */
#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
#define zlib_version zlibVersion()
/* for compatibility with versions < 1.0.2 */
/* basic functions */
extern const char * EXPORT zlibVersion OF((void));
/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
If the first character differs, the library code actually used is
not compatible with the zlib.h header file used by the application.
This check is automatically made by deflateInit and inflateInit.
*/
/*
extern int EXPORT deflateInit OF((z_streamp strm, int level));
Initializes the internal stream state for compression. The fields
zalloc, zfree and opaque must be initialized before by the caller.
If zalloc and zfree are set to Z_NULL, deflateInit updates them to
use default allocation functions.
The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
1 gives best speed, 9 gives best compression, 0 gives no compression at
all (the input data is simply copied a block at a time).
Z_DEFAULT_COMPRESSION requests a default compromise between speed and
compression (currently equivalent to level 6).
deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if level is not a valid compression level,
Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
with the version assumed by the caller (ZLIB_VERSION).
msg is set to null if there is no error message. deflateInit does not
perform any compression: this will be done by deflate().
*/
extern int EXPORT deflate OF((z_streamp strm, int flush));
/*
deflate compresses as much data as possible, and stops when the input
buffer becomes empty or the output buffer becomes full. It may introduce some
output latency (reading input without producing any output) except when
forced to flush.
The detailed semantics are as follows. deflate performs one or both of the
following actions:
- Compress more input starting at next_in and update next_in and avail_in
accordingly. If not all input can be processed (because there is not
enough room in the output buffer), next_in and avail_in are updated and
processing will resume at this point for the next call of deflate().
- Provide more output starting at next_out and update next_out and avail_out
accordingly. This action is forced if the parameter flush is non zero.
Forcing flush frequently degrades the compression ratio, so this parameter
should be set only when necessary (in interactive applications).
Some output may be provided even if flush is not set.
Before the call of deflate(), the application should ensure that at least
one of the actions is possible, by providing more input and/or consuming
more output, and updating avail_in or avail_out accordingly; avail_out
should never be zero before the call. The application can consume the
compressed output when it wants, for example when the output buffer is full
(avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
and with zero avail_out, it must be called again after making room in the
output buffer because there might be more output pending.
If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
flushed to the output buffer and the output is aligned on a byte boundary, so
that the decompressor can get all input data available so far. (In particular
avail_in is zero after the call if enough output space has been provided
before the call.) Flushing may degrade compression for some compression
algorithms and so it should be used only when necessary.
If flush is set to Z_FULL_FLUSH, all output is flushed as with
Z_SYNC_FLUSH, and the compression state is reset so that decompression can
restart from this point if previous compressed data has been damaged or if
random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
the compression.
If deflate returns with avail_out == 0, this function must be called again
with the same value of the flush parameter and more output space (updated
avail_out), until the flush is complete (deflate returns with non-zero
avail_out).
If the parameter flush is set to Z_FINISH, pending input is processed,
pending output is flushed and deflate returns with Z_STREAM_END if there
was enough output space; if deflate returns with Z_OK, this function must be
called again with Z_FINISH and more output space (updated avail_out) but no
more input data, until it returns with Z_STREAM_END or an error. After
deflate has returned Z_STREAM_END, the only possible operations on the
stream are deflateReset or deflateEnd.
Z_FINISH can be used immediately after deflateInit if all the compression
is to be done in a single step. In this case, avail_out must be at least
0.1% larger than avail_in plus 12 bytes. If deflate does not return
Z_STREAM_END, then it must be called again as described above.
deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes).
deflate() may update data_type if it can make a good guess about
the input data type (Z_ASCII or Z_BINARY). In doubt, the data is considered
binary. This field is only for information purposes and does not affect
the compression algorithm in any manner.
deflate() returns Z_OK if some progress has been made (more input
processed or more output produced), Z_STREAM_END if all input has been
consumed and all output has been produced (only when flush is set to
Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible.
*/
extern int EXPORT deflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
This function discards any unprocessed input and does not flush any
pending output.
deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
stream state was inconsistent, Z_DATA_ERROR if the stream was freed
prematurely (some input or output was discarded). In the error case,
msg may be set but then points to a static string (which must not be
deallocated).
*/
/*
extern int EXPORT inflateInit OF((z_streamp strm));
Initializes the internal stream state for decompression. The fields
next_in, avail_in, zalloc, zfree and opaque must be initialized before by
the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
value depends on the compression method), inflateInit determines the
compression method from the zlib header and allocates all data structures
accordingly; otherwise the allocation will be deferred to the first call of
inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
use default allocation functions.
inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
version assumed by the caller. msg is set to null if there is no error
message. inflateInit does not perform any decompression apart from reading
the zlib header if present: this will be done by inflate(). (So next_in and
avail_in may be modified, but next_out and avail_out are unchanged.)
*/
extern int EXPORT inflate OF((z_streamp strm, int flush));
/*
inflate decompresses as much data as possible, and stops when the input
buffer becomes empty or the output buffer becomes full. It may some
introduce some output latency (reading input without producing any output)
except when forced to flush.
The detailed semantics are as follows. inflate performs one or both of the
following actions:
- Decompress more input starting at next_in and update next_in and avail_in
accordingly. If not all input can be processed (because there is not
enough room in the output buffer), next_in is updated and processing
will resume at this point for the next call of inflate().
- Provide more output starting at next_out and update next_out and avail_out
accordingly. inflate() provides as much output as possible, until there
is no more input data or no more space in the output buffer (see below
about the flush parameter).
Before the call of inflate(), the application should ensure that at least
one of the actions is possible, by providing more input and/or consuming
more output, and updating the next_* and avail_* values accordingly.
The application can consume the uncompressed output when it wants, for
example when the output buffer is full (avail_out == 0), or after each
call of inflate(). If inflate returns Z_OK and with zero avail_out, it
must be called again after making room in the output buffer because there
might be more output pending.
If the parameter flush is set to Z_SYNC_FLUSH, inflate flushes as much
output as possible to the output buffer. The flushing behavior of inflate is
not specified for values of the flush parameter other than Z_SYNC_FLUSH
and Z_FINISH, but the current implementation actually flushes as much output
as possible anyway.
inflate() should normally be called until it returns Z_STREAM_END or an
error. However if all decompression is to be performed in a single step
(a single call of inflate), the parameter flush should be set to
Z_FINISH. In this case all pending input is processed and all pending
output is flushed; avail_out must be large enough to hold all the
uncompressed data. (The size of the uncompressed data may have been saved
by the compressor for this purpose.) The next operation on this stream must
be inflateEnd to deallocate the decompression state. The use of Z_FINISH
is never required, but can be used to inform inflate that a faster routine
may be used for the single inflate() call.
If a preset dictionary is needed at this point (see inflateSetDictionary
below), inflate sets strm-adler to the adler32 checksum of the
dictionary chosen by the compressor and returns Z_NEED_DICT; otherwise
it sets strm->adler to the adler32 checksum of all output produced
so far (that is, total_out bytes) and returns Z_OK, Z_STREAM_END or
an error code as described below. At the end of the stream, inflate()
checks that its computed adler32 checksum is equal to that saved by the
compressor and returns Z_STREAM_END only if the checksum is correct.
inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has
been reached and all uncompressed output has been produced, Z_NEED_DICT if a
preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
corrupted (input stream not conforming to the zlib format or incorrect
adler32 checksum), Z_STREAM_ERROR if the stream structure was inconsistent
(for example if next_in or next_out was NULL), Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if no progress is possible or if there was not
enough room in the output buffer when Z_FINISH is used. In the Z_DATA_ERROR
case, the application may then call inflateSync to look for a good
compression block.
*/
extern int EXPORT inflateEnd OF((z_streamp strm));
/*
All dynamically allocated data structures for this stream are freed.
This function discards any unprocessed input and does not flush any
pending output.
inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
was inconsistent. In the error case, msg may be set but then points to a
static string (which must not be deallocated).
*/
/* Advanced functions */
/*
The following functions are needed only in some special applications.
*/
/*
extern int EXPORT deflateInit2 OF((z_streamp strm,
int level,
int method,
int windowBits,
int memLevel,
int strategy));
This is another version of deflateInit with more compression options. The
fields next_in, zalloc, zfree and opaque must be initialized before by
the caller.
The method parameter is the compression method. It must be Z_DEFLATED in
this version of the library.
The windowBits parameter is the base two logarithm of the window size
(the size of the history buffer). It should be in the range 8..15 for this
version of the library. Larger values of this parameter result in better
compression at the expense of memory usage. The default value is 15 if
deflateInit is used instead.
The memLevel parameter specifies how much memory should be allocated
for the internal compression state. memLevel=1 uses minimum memory but
is slow and reduces compression ratio; memLevel=9 uses maximum memory
for optimal speed. The default value is 8. See zconf.h for total memory
usage as a function of windowBits and memLevel.
The strategy parameter is used to tune the compression algorithm. Use the
value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
filter (or predictor), or Z_HUFFMAN_ONLY to force Huffman encoding only (no
string match). Filtered data consists mostly of small values with a
somewhat random distribution. In this case, the compression algorithm is
tuned to compress them better. The effect of Z_FILTERED is to force more
Huffman coding and less string matching; it is somewhat intermediate
between Z_DEFAULT and Z_HUFFMAN_ONLY. The strategy parameter only affects
the compression ratio but not the correctness of the compressed output even
if it is not set appropriately.
deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
method). msg is set to null if there is no error message. deflateInit2 does
not perform any compression: this will be done by deflate().
*/
extern int EXPORT deflateSetDictionary OF((z_streamp strm,
const Bytef *dictionary,
uInt dictLength));
/*
Initializes the compression dictionary from the given byte sequence
without producing any compressed output. This function must be called
immediately after deflateInit or deflateInit2, before any call of
deflate. The compressor and decompressor must use exactly the same
dictionary (see inflateSetDictionary).
The dictionary should consist of strings (byte sequences) that are likely
to be encountered later in the data to be compressed, with the most commonly
used strings preferably put towards the end of the dictionary. Using a
dictionary is most useful when the data to be compressed is short and can be
predicted with good accuracy; the data can then be compressed better than
with the default empty dictionary.
Depending on the size of the compression data structures selected by
deflateInit or deflateInit2, a part of the dictionary may in effect be
discarded, for example if the dictionary is larger than the window size in
deflate or deflate2. Thus the strings most likely to be useful should be
put at the end of the dictionary, not at the front.
Upon return of this function, strm->adler is set to the Adler32 value
of the dictionary; the decompressor may later use this value to determine
which dictionary has been used by the compressor. (The Adler32 value
applies to the whole dictionary even if only a subset of the dictionary is
actually used by the compressor.)
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
parameter is invalid (such as NULL dictionary) or the stream state is
inconsistent (for example if deflate has already been called for this stream
or if the compression method is bsort). deflateSetDictionary does not
perform any compression: this will be done by deflate().
*/
extern int EXPORT deflateCopy OF((z_streamp dest,
z_streamp source));
/*
Sets the destination stream as a complete copy of the source stream.
This function can be useful when several compression strategies will be
tried, for example when there are several ways of pre-processing the input
data with a filter. The streams that will be discarded should then be freed
by calling deflateEnd. Note that deflateCopy duplicates the internal
compression state which can be quite large, so this strategy is slow and
can consume lots of memory.
deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
(such as zalloc being NULL). msg is left unchanged in both source and
destination.
*/
extern int EXPORT deflateReset OF((z_streamp strm));
/*
This function is equivalent to deflateEnd followed by deflateInit,
but does not free and reallocate all the internal compression state.
The stream will keep the same compression level and any other attributes
that may have been set by deflateInit2.
deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent (such as zalloc or state being NULL).
*/
extern int EXPORT deflateParams OF((z_streamp strm, int level, int strategy));
/*
Dynamically update the compression level and compression strategy. The
interpretation of level and strategy is as in deflateInit2. This can be
used to switch between compression and straight copy of the input data, or
to switch to a different kind of input data requiring a different
strategy. If the compression level is changed, the input available so far
is compressed with the old level (and may be flushed); the new level will
take effect only at the next call of deflate().
Before the call of deflateParams, the stream state must be set as for
a call of deflate(), since the currently available input may have to
be compressed and flushed. In particular, strm->avail_out must be non-zero.
deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
if strm->avail_out was zero.
*/
/*
extern int EXPORT inflateInit2 OF((z_streamp strm,
int windowBits));
This is another version of inflateInit with an extra parameter. The
fields next_in, avail_in, zalloc, zfree and opaque must be initialized
before by the caller.
The windowBits parameter is the base two logarithm of the maximum window
size (the size of the history buffer). It should be in the range 8..15 for
this version of the library. The default value is 15 if inflateInit is used
instead. If a compressed stream with a larger window size is given as
input, inflate() will return with the error code Z_DATA_ERROR instead of
trying to allocate a larger window.
inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_STREAM_ERROR if a parameter is invalid (such as a negative
memLevel). msg is set to null if there is no error message. inflateInit2
does not perform any decompression apart from reading the zlib header if
present: this will be done by inflate(). (So next_in and avail_in may be
modified, but next_out and avail_out are unchanged.)
*/
extern int EXPORT inflateSetDictionary OF((z_streamp strm,
const Bytef *dictionary,
uInt dictLength));
/*
Initializes the decompression dictionary from the given uncompressed byte
sequence. This function must be called immediately after a call of inflate
if this call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the Adler32 value returned by this call of
inflate. The compressor and decompressor must use exactly the same
dictionary (see deflateSetDictionary).
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (such as NULL dictionary) or the stream state is
inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
expected one (incorrect Adler32 value). inflateSetDictionary does not
perform any decompression: this will be done by subsequent calls of
inflate().
*/
extern int EXPORT inflateSync OF((z_streamp strm));
/*
Skips invalid compressed data until a full flush point (see above the
description of deflate with Z_FULL_FLUSH) can be found, or until all
available input is skipped. No output is provided.
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
if no more input was provided, Z_DATA_ERROR if no flush point has been found,
or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
case, the application may save the current current value of total_in which
indicates where valid compressed data was found. In the error case, the
application may repeatedly call inflateSync, providing more input each time,
until success or end of the input data.
*/
extern int EXPORT inflateReset OF((z_streamp strm));
/*
This function is equivalent to inflateEnd followed by inflateInit,
but does not free and reallocate all the internal decompression state.
The stream will keep attributes that may have been set by inflateInit2.
inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent (such as zalloc or state being NULL).
*/
/* utility functions */
/*
The following utility functions are implemented on top of the
basic stream-oriented functions. To simplify the interface, some
default options are assumed (compression level and memory usage,
standard memory allocation functions). The source code of these
utility functions can easily be modified if you need special options.
*/
extern int EXPORT compress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
/*
Compresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be at least 0.1% larger than
sourceLen plus 12 bytes. Upon exit, destLen is the actual size of the
compressed buffer.
This function can be used to compress a whole file at once if the
input file is mmap'ed.
compress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer.
*/
extern int EXPORT compress2 OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen,
int level));
/*
Compresses the source buffer into the destination buffer. The level
parameter has the same meaning as in deflateInit. sourceLen is the byte
length of the source buffer. Upon entry, destLen is the total size of the
destination buffer, which must be at least 0.1% larger than sourceLen plus
12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
memory, Z_BUF_ERROR if there was not enough room in the output buffer,
Z_STREAM_ERROR if the level parameter is invalid.
*/
extern int EXPORT uncompress OF((Bytef *dest, uLongf *destLen,
const Bytef *source, uLong sourceLen));
/*
Decompresses the source buffer into the destination buffer. sourceLen is
the byte length of the source buffer. Upon entry, destLen is the total
size of the destination buffer, which must be large enough to hold the
entire uncompressed data. (The size of the uncompressed data must have
been saved previously by the compressor and transmitted to the decompressor
by some mechanism outside the scope of this compression library.)
Upon exit, destLen is the actual size of the compressed buffer.
This function can be used to decompress a whole file at once if the
input file is mmap'ed.
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted.
*/
typedef voidp gzFile;
extern gzFile EXPORT gzopen OF((const char *path, const char *mode));
/*
Opens a gzip (.gz) file for reading or writing. The mode parameter
is as in fopen ("rb" or "wb") but can also include a compression level
("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
Huffman only compression as in "wb1h". (See the description
of deflateInit2 for more information about the strategy parameter.)
gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression.
gzopen returns NULL if the file could not be opened or if there was
insufficient memory to allocate the (de)compression state; errno
can be checked to distinguish the two cases (if errno is zero, the
zlib error is Z_MEM_ERROR). */
extern gzFile EXPORT gzdopen OF((int fd, const char *mode));
/*
gzdopen() associates a gzFile with the file descriptor fd. File
descriptors are obtained from calls like open, dup, creat, pipe or
fileno (in the file has been previously opened with fopen).
The mode parameter is as in gzopen.
The next call of gzclose on the returned gzFile will also close the
file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
gzdopen returns NULL if there was insufficient memory to allocate
the (de)compression state.
*/
extern int EXPORT gzsetparams OF((gzFile file, int level, int strategy));
/*
Dynamically update the compression level or strategy. See the description
of deflateInit2 for the meaning of these parameters.
gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
opened for writing.
*/
extern int EXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/*
Reads the given number of uncompressed bytes from the compressed file.
If the input file was not in gzip format, gzread copies the given number
of bytes into the buffer.
gzread returns the number of uncompressed bytes actually read (0 for
end of file, -1 for error). */
extern int EXPORT gzwrite OF((gzFile file, const voidp buf, unsigned len));
/*
Writes the given number of uncompressed bytes into the compressed file.
gzwrite returns the number of uncompressed bytes actually written
(0 in case of error).
*/
extern int EXPORTVA gzprintf OF((gzFile file, const char *format, ...));
/*
Converts, formats, and writes the args to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of
uncompressed bytes actually written (0 in case of error).
*/
extern int EXPORT gzputc OF((gzFile file, int c));
/*
Writes c, converted to an unsigned char, into the compressed file.
gzputc returns the value that was written, or -1 in case of error.
*/
extern int EXPORT gzgetc OF((gzFile file));
/*
Reads one byte from the compressed file. gzgetc returns this byte
or -1 in case of end of file or error.
*/
extern int EXPORT gzflush OF((gzFile file, int flush));
/*
Flushes all pending output into the compressed file. The parameter
flush is as in the deflate() function. The return value is the zlib
error number (see function gzerror below). gzflush returns Z_OK if
the flush parameter is Z_FINISH and all output could be flushed.
gzflush should be called only when strictly necessary because it can
degrade compression.
*/
extern z_off_t EXPORT gzseek OF((gzFile file, z_off_t offset, int whence));
/*
Sets the starting position for the next gzread or gzwrite on the given
compressed file. The offset represents a number of bytes in the
uncompressed data stream. The whence parameter is defined as in lseek(2);
the value SEEK_END is not supported.
If the file is opened for reading, this function is emulated but can be
extremely slow. If the file is opened for writing, only forward seeks are
supported; gzseek then compresses a sequence of zeroes up to the new
starting position.
gzseek returns the resulting offset location as measured in bytes from
the beginning of the uncompressed stream, or -1 in case of error, in
particular if the file is opened for writing and the new starting position
would be before the current position.
*/
extern int EXPORT gzrewind OF((gzFile file));
/*
Rewinds the given file. This function is supported only for reading.
gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
*/
extern z_off_t EXPORT gztell OF((gzFile file));
/*
Returns the starting position for the next gzread or gzwrite on the
given compressed file. This position represents a number of bytes in the
uncompressed data stream.
gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
*/
extern int EXPORT gzeof OF((gzFile file));
/*
Returns 1 when EOF has previously been detected reading the given
input stream, otherwise zero.
*/
extern int EXPORT gzclose OF((gzFile file));
/*
Flushes all pending output if necessary, closes the compressed file
and deallocates all the (de)compression state. The return value is the zlib
error number (see function gzerror below).
*/
extern const char * EXPORT gzerror OF((gzFile file, int *errnum));
/*
Returns the error message for the last error which occurred on the
given compressed file. errnum is set to zlib error number. If an
error occurred in the file system and not in the compression library,
errnum is set to Z_ERRNO and the application may consult errno
to get the exact error code.
*/
/* checksum functions */
/*
These functions are not related to compression but are exported
anyway because they might be useful in applications using the
compression library.
*/
extern uLong EXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
/*
Update a running Adler-32 checksum with the bytes buf[0..len-1] and
return the updated checksum. If buf is NULL, this function returns
the required initial value for the checksum.
An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
much faster. Usage example:
uLong adler = adler32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
adler = adler32(adler, buffer, length);
}
if (adler != original_adler) error();
*/
extern uLong EXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/*
Update a running crc with the bytes buf[0..len-1] and return the updated
crc. If buf is NULL, this function returns the required initial value
for the crc. Pre- and post-conditioning (one's complement) is performed
within this function so it shouldn't be done by the application.
Usage example:
uLong crc = crc32(0L, Z_NULL, 0);
while (read_buffer(buffer, length) != EOF) {
crc = crc32(crc, buffer, length);
}
if (crc != original_crc) error();
*/
/* various hacks, don't look :) */
/* deflateInit and inflateInit are macros to allow checking the zlib version
* and the compiler's view of z_stream:
*/
extern int EXPORT deflateInit_ OF((z_streamp strm, int level,
const char *version, int stream_size));
extern int EXPORT inflateInit_ OF((z_streamp strm,
const char *version, int stream_size));
extern int EXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
int windowBits, int memLevel, int strategy,
const char *version, int stream_size));
extern int EXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
const char *version, int stream_size));
#define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit(strm) \
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
(strategy), ZLIB_VERSION, sizeof(z_stream))
#define inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
#if !defined(_Z_UTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;}; /* hack for buggy compilers */
#endif
extern const char * EXPORT zError OF((int err));
extern int EXPORT inflateSyncPoint OF((z_streamp z));
extern const uLongf * EXPORT get_crc_table OF((void));
#ifdef __cplusplus
}
#endif
#endif /* _ZLIB_H */

Binary file not shown.

BIN
LFtid1056/pqdif/lib/libz.a Normal file

Binary file not shown.

View File

@@ -0,0 +1,506 @@
#include "pqdif_semantic_ids.h"
#include <cstdio>
#include <sstream>
namespace pqdif_sem
{
// ============================================================================
// GUID <20><><EFBFBD><EFBFBD>
// ============================================================================
std::string GuidToString(const GUID& g)
{
char buf[64] = { 0 };
std::snprintf(
buf,
sizeof(buf),
"%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
g.Data1, g.Data2, g.Data3,
g.Data4[0], g.Data4[1],
g.Data4[2], g.Data4[3], g.Data4[4],
g.Data4[5], g.Data4[6], g.Data4[7]);
return std::string(buf);
}
// ============================================================================
// <20><><EFBFBD><EFBFBD><EFBFBD>͹̶<CDB9><CCB6><EFBFBD>
// <20><>Դ<EFBFBD><D4B4>PDF <20><> B.2 / B.3 / B.4 + pqdif/include/pqdif_id.h
// ============================================================================
const UIntSemanticEntry kPhaseTable[] = {
{ ID_PHASE_NONE, "ID_PHASE_NONE", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagPhaseID", "δָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" },
{ ID_PHASE_AN, "ID_PHASE_AN", "A-N", "tagPhaseID", "A <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" },
{ ID_PHASE_BN, "ID_PHASE_BN", "B-N", "tagPhaseID", "B <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" },
{ ID_PHASE_CN, "ID_PHASE_CN", "C-N", "tagPhaseID", "C <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" },
{ ID_PHASE_NG, "ID_PHASE_NG", "N-G", "tagPhaseID", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶Ե<EFBFBD>" },
{ ID_PHASE_AB, "ID_PHASE_AB", "A-B", "tagPhaseID", "A-B <20><><EFBFBD><EFBFBD>" },
{ ID_PHASE_BC, "ID_PHASE_BC", "B-C", "tagPhaseID", "B-C <20><><EFBFBD><EFBFBD>" },
{ ID_PHASE_CA, "ID_PHASE_CA", "C-A", "tagPhaseID", "C-A <20><><EFBFBD><EFBFBD>" },
{ ID_PHASE_RES, "ID_PHASE_RES", "ʣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagPhaseID", "Residual" },
{ ID_PHASE_NET, "ID_PHASE_NET", "<EFBFBD><EFBFBD>ֵ", "tagPhaseID", "Net" },
{ ID_PHASE_TOTAL, "ID_PHASE_TOTAL", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagPhaseID", "Total" },
{ ID_PHASE_LN_AVE, "ID_PHASE_LN_AVE", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹƽ<EFBFBD><EFBFBD>", "tagPhaseID", "LN average" },
{ ID_PHASE_LL_AVE, "ID_PHASE_LL_AVE", "<EFBFBD>ߵ<EFBFBD>ѹƽ<EFBFBD><EFBFBD>", "tagPhaseID", "LL average" },
{ ID_PHASE_WORST, "ID_PHASE_WORST", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagPhaseID", "Worst phase" },
{ ID_PHASE_PLUS, "ID_PHASE_PLUS", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagPhaseID", "Plus / forward" },
{ ID_PHASE_MINUS, "ID_PHASE_MINUS", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagPhaseID", "Minus / reverse" },
{ ID_PHASE_GENERAL_1, "ID_PHASE_GENERAL_1", "ͨ<EFBFBD><EFBFBD>1", "tagPhaseID", "General slot 1" },
{ ID_PHASE_GENERAL_2, "ID_PHASE_GENERAL_2", "ͨ<EFBFBD><EFBFBD>2", "tagPhaseID", "General slot 2" },
{ ID_PHASE_GENERAL_3, "ID_PHASE_GENERAL_3", "ͨ<EFBFBD><EFBFBD>3", "tagPhaseID", "General slot 3" },
{ ID_PHASE_GENERAL_4, "ID_PHASE_GENERAL_4", "ͨ<EFBFBD><EFBFBD>4", "tagPhaseID", "General slot 4" },
{ ID_PHASE_GENERAL_5, "ID_PHASE_GENERAL_5", "ͨ<EFBFBD><EFBFBD>5", "tagPhaseID", "General slot 5" },
{ ID_PHASE_GENERAL_6, "ID_PHASE_GENERAL_6", "ͨ<EFBFBD><EFBFBD>6", "tagPhaseID", "General slot 6" },
{ ID_PHASE_GENERAL_7, "ID_PHASE_GENERAL_7", "ͨ<EFBFBD><EFBFBD>7", "tagPhaseID", "General slot 7" },
{ ID_PHASE_GENERAL_8, "ID_PHASE_GENERAL_8", "ͨ<EFBFBD><EFBFBD>8", "tagPhaseID", "General slot 8" },
{ ID_PHASE_GENERAL_9, "ID_PHASE_GENERAL_9", "ͨ<EFBFBD><EFBFBD>9", "tagPhaseID", "General slot 9" },
{ ID_PHASE_GENERAL_10, "ID_PHASE_GENERAL_10", "ͨ<EFBFBD><EFBFBD>10", "tagPhaseID", "General slot 10" },
{ ID_PHASE_GENERAL_11, "ID_PHASE_GENERAL_11", "ͨ<EFBFBD><EFBFBD>11", "tagPhaseID", "General slot 11" },
{ ID_PHASE_GENERAL_12, "ID_PHASE_GENERAL_12", "ͨ<EFBFBD><EFBFBD>12", "tagPhaseID", "General slot 12" },
{ ID_PHASE_GENERAL_13, "ID_PHASE_GENERAL_13", "ͨ<EFBFBD><EFBFBD>13", "tagPhaseID", "General slot 13" },
{ ID_PHASE_GENERAL_14, "ID_PHASE_GENERAL_14", "ͨ<EFBFBD><EFBFBD>14", "tagPhaseID", "General slot 14" },
{ ID_PHASE_GENERAL_15, "ID_PHASE_GENERAL_15", "ͨ<EFBFBD><EFBFBD>15", "tagPhaseID", "General slot 15" },
{ ID_PHASE_GENERAL_16, "ID_PHASE_GENERAL_16", "ͨ<EFBFBD><EFBFBD>16", "tagPhaseID", "General slot 16" }
};
const std::size_t kPhaseTableSize = sizeof(kPhaseTable) / sizeof(kPhaseTable[0]);
const UIntSemanticEntry kQuantityMeasuredTable[] = {
{ ID_QM_NONE, "ID_QM_NONE", "δָ<EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "δָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" },
{ ID_QM_VOLTAGE, "ID_QM_VOLTAGE", "<EFBFBD><EFBFBD>ѹ", "tagQuantityMeasuredID", "Voltage" },
{ ID_QM_CURRENT, "ID_QM_CURRENT", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Current" },
{ ID_QM_POWER, "ID_QM_POWER", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Power" },
{ ID_QM_ENERGY, "ID_QM_ENERGY", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Energy" },
{ ID_QM_TEMPERATURE, "ID_QM_TEMPERATURE", "<EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Temperature" },
{ ID_QM_PRESSURE, "ID_QM_PRESSURE", "ѹ<EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Pressure" },
{ ID_QM_CHARGE, "ID_QM_CHARGE", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Charge" },
{ ID_QM_EFIELD, "ID_QM_EFIELD", "<EFBFBD>", "tagQuantityMeasuredID", "Electric field" },
{ ID_QM_MFIELD, "ID_QM_MFIELD", "<EFBFBD>ų<EFBFBD>", "tagQuantityMeasuredID", "Magnetic field" },
{ ID_QM_VELOCITY, "ID_QM_VELOCITY", "<EFBFBD>ٶ<EFBFBD>", "tagQuantityMeasuredID", "Velocity" },
{ ID_QM_BEARING, "ID_QM_BEARING", "<EFBFBD><EFBFBD>λ", "tagQuantityMeasuredID", "Bearing" },
{ ID_QM_FORCE, "ID_QM_FORCE", "<EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Force" },
{ ID_QM_TORQUE, "ID_QM_TORQUE", "ת<EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Torque" },
{ ID_QM_POSITION, "ID_QM_POSITION", "λ<EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Position" },
{ ID_QM_FLUXLINKAGE, "ID_QM_FLUXLINKAGE", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Flux linkage" },
{ ID_QM_FLUXDENSITY, "ID_QM_FLUXDENSITY", "<EFBFBD><EFBFBD>ͨ<EFBFBD>ܶ<EFBFBD>", "tagQuantityMeasuredID", "Flux density" },
{ ID_QM_STATUS, "ID_QM_STATUS", "״̬<EFBFBD><EFBFBD>", "tagQuantityMeasuredID", "Status quantity" }
};
const std::size_t kQuantityMeasuredTableSize = sizeof(kQuantityMeasuredTable) / sizeof(kQuantityMeasuredTable[0]);
const UIntSemanticEntry kQuantityUnitsTable[] = {
{ ID_QU_NONE, "ID_QU_NONE", "<EFBFBD>޵<EFBFBD>λ", "tagQuantityUnitsID", "No unit" },
{ ID_QU_TIMESTAMP, "ID_QU_TIMESTAMP", "ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityUnitsID", "Timestamp" },
{ ID_QU_SECONDS, "ID_QU_SECONDS", "<EFBFBD><EFBFBD>", "tagQuantityUnitsID", "Seconds" },
{ ID_QU_CYCLES, "ID_QU_CYCLES", "<EFBFBD>ܲ<EFBFBD>", "tagQuantityUnitsID", "Cycles" },
{ ID_QU_VOLTS, "ID_QU_VOLTS", "V", "tagQuantityUnitsID", "Volts" },
{ ID_QU_AMPS, "ID_QU_AMPS", "A", "tagQuantityUnitsID", "Amps" },
{ ID_QU_VA, "ID_QU_VA", "VA", "tagQuantityUnitsID", "Volt-amps" },
{ ID_QU_WATTS, "ID_QU_WATTS", "W", "tagQuantityUnitsID", "Watts" },
{ ID_QU_VARS, "ID_QU_VARS", "var", "tagQuantityUnitsID", "Vars" },
{ ID_QU_OHMS, "ID_QU_OHMS", "<EFBFBD><EFBFBD>", "tagQuantityUnitsID", "Ohms" },
{ ID_QU_SIEMENS, "ID_QU_SIEMENS", "S", "tagQuantityUnitsID", "Siemens" },
{ ID_QU_VOLTSPERAMP, "ID_QU_VOLTSPERAMP", "V/A", "tagQuantityUnitsID", "Volts per amp" },
{ ID_QU_JOULES, "ID_QU_JOULES", "J", "tagQuantityUnitsID", "Joules" },
{ ID_QU_HERTZ, "ID_QU_HERTZ", "Hz", "tagQuantityUnitsID", "Hertz" },
{ ID_QU_CELCIUS, "ID_QU_CELCIUS", "<EFBFBD><EFBFBD>", "tagQuantityUnitsID", "Celsius" },
{ ID_QU_DEGREES, "ID_QU_DEGREES", "<EFBFBD><EFBFBD>", "tagQuantityUnitsID", "Degrees" },
{ ID_QU_DB, "ID_QU_DB", "dB", "tagQuantityUnitsID", "Decibel" },
{ ID_QU_PERCENT, "ID_QU_PERCENT", "%", "tagQuantityUnitsID", "Percent" },
{ ID_QU_PERUNIT, "ID_QU_PERUNIT", "pu", "tagQuantityUnitsID", "Per-unit" },
{ ID_QU_SAMPLES, "ID_QU_SAMPLES", "samples", "tagQuantityUnitsID", "Samples" },
{ ID_QU_VARHOURS, "ID_QU_VARHOURS", "varh", "tagQuantityUnitsID", "Var-hours" },
{ ID_QU_WATTHOURS, "ID_QU_WATTHOURS", "Wh", "tagQuantityUnitsID", "Watt-hours" },
{ ID_QU_VAHOURS, "ID_QU_VAHOURS", "VAh", "tagQuantityUnitsID", "VA-hours" },
{ ID_QU_MPS, "ID_QU_MPS", "m/s", "tagQuantityUnitsID", "Meters per second" },
{ ID_QU_MPH, "ID_QU_MPH", "mph", "tagQuantityUnitsID", "Miles per hour" },
{ ID_QU_BARS, "ID_QU_BARS", "bar", "tagQuantityUnitsID", "Bars" },
{ ID_QU_PASCALS, "ID_QU_PASCALS", "Pa", "tagQuantityUnitsID", "Pascals" },
{ ID_QU_NEWTONS, "ID_QU_NEWTONS", "N", "tagQuantityUnitsID", "Newtons" },
{ ID_QU_NEWTONMETERS, "ID_QU_NEWTONMETERS", "N<EFBFBD><EFBFBD>m", "tagQuantityUnitsID", "Newton meters" },
{ ID_QU_RPM, "ID_QU_RPM", "rpm", "tagQuantityUnitsID", "Rotations per minute" },
{ ID_QU_RADPERSEC, "ID_QU_RADPERSEC", "rad/s", "tagQuantityUnitsID", "Radians per second" },
{ ID_QU_METERS, "ID_QU_METERS", "m", "tagQuantityUnitsID", "Meters" },
{ ID_QU_WEBERTURNS, "ID_QU_WEBERTURNS", "Wb<EFBFBD><EFBFBD>turn", "tagQuantityUnitsID", "Weber-turns" },
{ ID_QU_TESLAS, "ID_QU_TESLAS", "T", "tagQuantityUnitsID", "Teslas" },
{ ID_QU_WEBERS, "ID_QU_WEBERS", "Wb", "tagQuantityUnitsID", "Webers" },
{ ID_QU_VOLTSPERVOLT, "ID_QU_VOLTSPERVOLT", "V/V", "tagQuantityUnitsID", "Volts per volt" },
{ ID_QU_AMPSPERAMP, "ID_QU_AMPSPERAMP", "A/A", "tagQuantityUnitsID", "Amps per amp" },
{ ID_QU_AMPSPERVOLT, "ID_QU_AMPSPERVOLT", "A/V", "tagQuantityUnitsID", "Amps per volt" }
};
const std::size_t kQuantityUnitsTableSize = sizeof(kQuantityUnitsTable) / sizeof(kQuantityUnitsTable[0]);
const UIntSemanticEntry kStorageMethodTable[] = {
{ ID_SERIES_METHOD_VALUES, "ID_SERIES_METHOD_VALUES", "ֱ<EFBFBD>Ӵ<EFBFBD>ֵ", "tagStorageMethodID", "SeriesValues ֱ<>ӱ<EFBFBD><D3B1><EFBFBD>ԭʼֵ" },
{ ID_SERIES_METHOD_SCALED, "ID_SERIES_METHOD_SCALED", "<EFBFBD><EFBFBD><EFBFBD>Ŵ<EFBFBD>ֵ", "tagStorageMethodID", "<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> scale/offset <20><><EFBFBD><EFBFBD>" },
{ ID_SERIES_METHOD_INCREMENT, "ID_SERIES_METHOD_INCREMENT", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ", "tagStorageMethodID", "<EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>ԭ" }
};
const std::size_t kStorageMethodTableSize = sizeof(kStorageMethodTable) / sizeof(kStorageMethodTable[0]);
const UIntSemanticEntry kTriggerMethodTable[] = {
{ ID_TRIGGER_METH_NONE, "ID_TRIGGER_METH_NONE", "<EFBFBD>޴<EFBFBD><EFBFBD><EFBFBD>", "tagTriggerMethodID", "<EFBFBD>޴<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ" },
{ ID_TRIGGER_METH_CHANNEL, "ID_TRIGGER_METH_CHANNEL", "ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagTriggerMethodID", "<EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" },
{ ID_TRIGGER_METH_PERIODIC, "ID_TRIGGER_METH_PERIODIC", "<EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD>", "tagTriggerMethodID", "<EFBFBD><EFBFBD><EFBFBD>̶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD>/<2F><>¼" },
{ ID_TRIGGER_METH_EXTERNAL, "ID_TRIGGER_METH_EXTERNAL", "<EFBFBD>ⲿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagTriggerMethodID", "<EFBFBD><EFBFBD><EFBFBD>ⲿ<EFBFBD>¼<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" },
{ ID_TRIGGER_METH_PERIODIC_STATS, "ID_TRIGGER_METH_PERIODIC_STATS", "ͳ<EFBFBD>ƴ<EFBFBD><EFBFBD><EFBFBD>", "tagTriggerMethodID", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD> observation" }
};
const std::size_t kTriggerMethodTableSize = sizeof(kTriggerMethodTable) / sizeof(kTriggerMethodTable[0]);
// ============================================================================
// GUID <20>͹̶<CDB9><CCB6><EFBFBD>
// <20><>Դ<EFBFBD><D4B4>PDF <20><> B.2 / B.4 + pqdif/include/pqdif_id.h
// <20><><EFBFBD><EFBFBD>д GUID ֵ<><D6B5>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pqdif_id.h <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ============================================================================
#define GUID_ENTRY(field_enum, guid_const, cn_name, tag_name, desc_text) \
{ guid_const, field_enum, #guid_const, cn_name, tag_name, desc_text }
// ------------------------------
// QuantityType<70><65>tagQuantityTypeID
// ------------------------------
const GuidSemanticEntry kQuantityTypeTable[] = {
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_WAVEFORM, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityTypeID", "<EFBFBD><EFBFBD>β<EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_VALUELOG, "ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>־", "tagQuantityTypeID", "ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD><EFBFBD>/<2F><><EFBFBD>Ƽ<EFBFBD>¼<EFBFBD><C2BC>ͳ<EFBFBD><CDB3>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD>ѡ"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_PHASOR, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityTypeID", "<EFBFBD><EFBFBD>ֵ/<2F><><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_RESPONSE, "<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityTypeID", "Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_FLASH, "<EFBFBD><EFBFBD><EFBFBD>䶨λ", "tagQuantityTypeID", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>/<2F><>Բ<EFBFBD><D4B2><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_HISTOGRAM, "ֱ<EFBFBD><EFBFBD>ͼ", "tagQuantityTypeID", "BINLOW/BINHIGH/BINID/COUNT"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_HISTOGRAM3D, "<EFBFBD><EFBFBD>άֱ<EFBFBD><EFBFBD>ͼ", "tagQuantityTypeID", "X/Y ˫ά BIN + COUNT"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_CPF, "<EFBFBD>ۼƸ<EFBFBD><EFBFBD><EFBFBD>", "tagQuantityTypeID", "PROB + VAL"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_XY, "XY <20><><EFBFBD><EFBFBD>", "tagQuantityTypeID", "˫ֵ<EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_MAGDUR, "<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>", "tagQuantityTypeID", "VAL + DURATION"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_XYZ, "XYZ <20><><EFBFBD><EFBFBD>", "tagQuantityTypeID", "<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_MAGDURTIME, "ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>", "tagQuantityTypeID", "TIME + VAL + DURATION"),
GUID_ENTRY(GuidSemanticField::QuantityType, ID_QT_MAGDURCOUNT, "ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityTypeID", "TIME + VAL + DURATION + COUNT")
};
const std::size_t kQuantityTypeTableSize = sizeof(kQuantityTypeTable) / sizeof(kQuantityTypeTable[0]);
// ------------------------------
// ValueType<70><65>tagValueTypeID
// <20><><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB> PDF <20><> B.2 <20><><EFBFBD><EFBFBD>ȷ<EFBFBD>г<EFBFBD><D0B3><EFBFBD> pqdif_id.h <20>д<EFBFBD><D0B4>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>ͳ<EFBFBD>Ƴ<EFBFBD><C6B3><EFBFBD><EFBFBD>
// ------------------------------
const GuidSemanticEntry kValueTypeTable[] = {
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_VAL, "ֵ", "tagValueTypeID", "Ĭ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_TIME, "ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_MIN, "<EFBFBD><EFBFBD>Сֵ", "tagValueTypeID", "ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Сֵ"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_MAX, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ", "tagValueTypeID", "ͳ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_AVG, "ƽ<EFBFBD><EFBFBD>ֵ", "tagValueTypeID", "ͳ<EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD>ֵ"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_INST, "˲ʱֵ", "tagValueTypeID", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ã<EFBFBD><EFBFBD>Ƽ<EFBFBD><EFBFBD><EFBFBD> VAL"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_PHASEANGLE, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> VAL <20><>ȫ<EFBFBD><C8AB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_PHASEANGLE_MIN, "<EFBFBD><EFBFBD>Сֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "<EFBFBD><EFBFBD>Ӧ MIN <20><><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_PHASEANGLE_MAX, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "<EFBFBD><EFBFBD>Ӧ MAX <20><><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_PHASEANGLE_AVG, "ƽ<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "<EFBFBD><EFBFBD>Ӧ AVG <20><><EFBFBD>е<EFBFBD><D0B5><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_AREA, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_LATITUDE, "γ<EFBFBD><EFBFBD>", "tagValueTypeID", "Latitude"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_DURATION, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>", "tagValueTypeID", "Duration"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_LONGITUDE, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "Longitude"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_POLARITY, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "Polarity"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_BINID, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "Histogram bin id"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_BINHIGH, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻ<EFBFBD>", "tagValueTypeID", "Histogram bin high"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_BINLOW, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD>", "tagValueTypeID", "Histogram bin low"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_XBINHIGH, "X<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻ<EFBFBD>", "tagValueTypeID", "3D histogram X high"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_XBINLOW, "X<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD>", "tagValueTypeID", "3D histogram X low"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_YBINHIGH, "Y<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻ<EFBFBD>", "tagValueTypeID", "3D histogram Y high"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_YBINLOW, "Y<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD>", "tagValueTypeID", "3D histogram Y low"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_COUNT, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_TRANSITION, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "VALUELOG <20><><EFBFBD><EFBFBD><EFBFBD>¼<EFBFBD><C2BC><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_PROB, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "<EFBFBD>ۼƸ<EFBFBD><EFBFBD>ʰٷֱ<EFBFBD>"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_INTERVAL, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagValueTypeID", "ͳ<EFBFBD>Ƽ<EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>ֵ"),
GUID_ENTRY(GuidSemanticField::ValueType, ID_SERIES_VALUE_TYPE_STATUS, "״̬", "tagValueTypeID", "״ֵ̬/<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>")
};
const std::size_t kValueTypeTableSize = sizeof(kValueTypeTable) / sizeof(kValueTypeTable[0]);
// ------------------------------
// QuantityCharacteristic<69><63>tagQuantityCharacteristicID
// <20><><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>ͳ<EFBFBD><CDB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD>á<EFBFBD><C3A1><EFBFBD><EFBFBD><EFBFBD> PDF <20><> B.2 <20><> pqdif_id.h <20>п<EFBFBD>ֱ<EFBFBD>Ӷ<EFBFBD><D3B6>ϵ<EFBFBD><CFB5>
// ------------------------------
const GuidSemanticEntry kQuantityCharacteristicTable[] = {
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_NONE, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "δ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_INSTANTANEOUS, "˲ʱ", "tagQuantityCharacteristicID", "Instantaneous f(t)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_SPECTRA, "Ƶ<EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Spectra F(F)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_PEAK, "<EFBFBD><EFBFBD>ֵ", "tagQuantityCharacteristicID", "Peak value"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_RMS, "<EFBFBD><EFBFBD>Чֵ", "tagQuantityCharacteristicID", "RMS value"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_HRMS, "г<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Чֵ", "tagQuantityCharacteristicID", "Harmonic RMS"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FREQUENCY, "Ƶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Frequency"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_TOTAL_THD, "<EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Total harmonic distortion (%)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_EVEN_THD, "ż<EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Even harmonic distortion (%)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_ODD_THD, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Odd harmonic distortion (%)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_CREST_FACTOR, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Crest factor"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FORM_FACTOR, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Form factor"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_ARITH_SUM, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Arithmetic sum"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_S0S1, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Zero sequence component unbalance (%)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_S2S1, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Negative sequence component unbalance (%)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_SPOS, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Positive sequence component"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_SNEG, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Negative sequence component"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_SZERO, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Zero sequence component"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_AVG_IMBAL, "ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Imbalance by max deviation from average"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_TOTAL_THD_RMS, "<EFBFBD><EFBFBD> THD(RMS)", "tagQuantityCharacteristicID", "Total THD normalized to RMS"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_ODD_THD_RMS, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> THD(RMS)", "tagQuantityCharacteristicID", "Odd THD normalized to RMS"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_EVEN_THD_RMS, "ż<EFBFBD><EFBFBD> THD(RMS)", "tagQuantityCharacteristicID", "Even THD normalized to RMS"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_TID, "<EFBFBD>ܼ<EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Total Interharmonic Distortion"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_TID_RMS, "<EFBFBD>ܼ<EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(RMS)", "tagQuantityCharacteristicID", "Total Interharmonic Distortion normalized to RMS"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_IHRMS, "<EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Чֵ", "tagQuantityCharacteristicID", "Interharmonic RMS"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_SPECTRA_HGROUP, "<EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Spectra by Harmonic Group index"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_SPECTRA_IGROUP, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>","tagQuantityCharacteristicID", "Spectra by Interharmonic Group index"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_TIF, "TIF", "tagQuantityCharacteristicID", "Telephone Influence Factor"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_MAG_AVG, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ", "tagQuantityCharacteristicID", "Flicker average RMS value"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_MAX_DVV, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> dV/V", "tagQuantityCharacteristicID", "dV/V base"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_FREQ_MAX, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Frequency of maximum flicker harmonic"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_MAG_MAX, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ", "tagQuantityCharacteristicID", "Magnitude of maximum flicker harmonic"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_WGT_AVG, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȩƽ<EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Spectrum weighted average"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_SPECTRUM, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƶ<EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Flicker spectrum VRMS(F)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_PST, "<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Short Term Flicker"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_PLT, "<EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Long Term Flicker"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_TIF_RMS, "TIF(RMS)", "tagQuantityCharacteristicID", "TIF normalized to RMS"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_FLKR_PLTSLIDE, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD> PLT", "tagQuantityCharacteristicID", "Sliding PLT"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_IT, "IT", "tagQuantityCharacteristicID", "IT"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_RMS_DEMAND, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Чֵ", "tagQuantityCharacteristicID", "RMS value of current for a demand interval"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_ANSI_TDF, "ANSI <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Transformer Derating Factor"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_K_FACTOR, "K <20><><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Transformer K Factor"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_TDD, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Total Demand Distortion"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_RMS_PEAK_DEMAND,"<EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Peak Demand Current"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_P, "<EFBFBD>й<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Real power (watts)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_Q, "<EFBFBD>޹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Reactive power (VAR)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_S, "<EFBFBD><EFBFBD><EFBFBD>ڹ<EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Apparent power (VA)"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_PF, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "True Power Factor"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_DF, "λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Displacement factor"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_P_DEMAND, "<EFBFBD>й<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Real power demand"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_Q_DEMAND, "<EFBFBD>޹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Reactive power demand"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_S_DEMAND, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Apparent power demand"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_DF_DEMAND, "λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Displacement factor demand"),
GUID_ENTRY(GuidSemanticField::QuantityCharacteristic, ID_QC_PF_DEMAND, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagQuantityCharacteristicID", "Power factor demand")
};
const std::size_t kQuantityCharacteristicTableSize =
sizeof(kQuantityCharacteristicTable) / sizeof(kQuantityCharacteristicTable[0]);
// ------------------------------
// DisturbanceCategory<72><79>tagDisturbanceCategoryID
// ͳ<><CDB3>ӳ<EFBFBD><D3B3><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ˣ<EFBFBD><CBA3><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD>ͳ<EFBFBD><CDB3>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>ֻ<EFBFBD><D6BB>ͷ<EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EEB3A3><EFBFBD><EFBFBD>PDF <20><> B.4 Ҳ<>ܶ<EFBFBD><DCB6>ϵĻ<CFB5><C4BB><EFBFBD><EFBFBD>
// ------------------------------
const GuidSemanticEntry kDisturbanceCategoryTable[] = {
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_NONE, "<EFBFBD><EFBFBD><EFBFBD>Ŷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagDisturbanceCategoryID", "No IEEE 1159 definition applicable"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_TRANSIENT, "˲̬", "tagDisturbanceCategoryID", "IEEE 1159 Transient"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_LONGDUR, "<EFBFBD><EFBFBD>ʱ RMS <20>", "tagDisturbanceCategoryID", "IEEE 1159 Long Duration RMS Variation"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_IMBALANCE, "<EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD>", "tagDisturbanceCategoryID", "IEEE 1159 Imbalance"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_POWERFREQVARIATION, "<EFBFBD><EFBFBD>Ƶ<EFBFBD>", "tagDisturbanceCategoryID", "IEEE 1159 Power Frequency Variation"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_VOLTAGEFLUCTUATION, "<EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>/<2F><><EFBFBD><EFBFBD>", "tagDisturbanceCategoryID", "IEEE 1159 Voltage Fluctuation"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_WAVEDISTORT, "<EFBFBD><EFBFBD><EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD>", "tagDisturbanceCategoryID", "IEEE 1159 Waveform Distortion"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_WAVEDISTORT_HARMONIC, "г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagDisturbanceCategoryID", "IEEE 1159 Harmonics Present"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_WAVEDISTORT_INTERHARMONIC, "<EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagDisturbanceCategoryID", "IEEE 1159 Interharmonics Present"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_WAVEDISTORT_NOTCHING, "ȱ<EFBFBD><EFBFBD>", "tagDisturbanceCategoryID", "IEEE 1159 Notching Present"),
GUID_ENTRY(GuidSemanticField::DisturbanceCategory, ID_DISTURB_1159_WAVEDISTORT_NOISE, "<EFBFBD><EFBFBD><EFBFBD><EFBFBD>", "tagDisturbanceCategoryID", "IEEE 1159 Noise Present")
};
const std::size_t kDisturbanceCategoryTableSize =
sizeof(kDisturbanceCategoryTable) / sizeof(kDisturbanceCategoryTable[0]);
#undef GUID_ENTRY
// ============================================================================
// <20><>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD>
// ============================================================================
const UIntSemanticEntry* FindUIntSemantic(
const UIntSemanticEntry* table,
std::size_t table_size,
uint32_t raw_value)
{
for (std::size_t i = 0; i < table_size; ++i)
{
if (table[i].raw_value == raw_value)
return &table[i];
}
return nullptr;
}
const UIntSemanticEntry* FindPhase(uint32_t raw_value)
{
return FindUIntSemantic(kPhaseTable, kPhaseTableSize, raw_value);
}
const UIntSemanticEntry* FindQuantityMeasured(uint32_t raw_value)
{
return FindUIntSemantic(kQuantityMeasuredTable, kQuantityMeasuredTableSize, raw_value);
}
const UIntSemanticEntry* FindQuantityUnits(uint32_t raw_value)
{
return FindUIntSemantic(kQuantityUnitsTable, kQuantityUnitsTableSize, raw_value);
}
const UIntSemanticEntry* FindStorageMethod(uint32_t raw_value)
{
return FindUIntSemantic(kStorageMethodTable, kStorageMethodTableSize, raw_value);
}
const UIntSemanticEntry* FindTriggerMethod(uint32_t raw_value)
{
return FindUIntSemantic(kTriggerMethodTable, kTriggerMethodTableSize, raw_value);
}
static std::string MakeUnknownUIntName(const char* prefix, uint32_t raw_value)
{
return std::string(prefix) + "(" + std::to_string(raw_value) + ")";
}
std::string FindPhaseName(uint32_t raw_value)
{
const auto* e = FindPhase(raw_value);
return e ? e->display_name : MakeUnknownUIntName("UNKNOWN_PHASE", raw_value);
}
std::string FindQuantityMeasuredName(uint32_t raw_value)
{
const auto* e = FindQuantityMeasured(raw_value);
return e ? e->display_name : MakeUnknownUIntName("UNKNOWN_MEASURED", raw_value);
}
std::string FindQuantityUnitsName(uint32_t raw_value)
{
const auto* e = FindQuantityUnits(raw_value);
return e ? e->display_name : MakeUnknownUIntName("UNKNOWN_UNIT", raw_value);
}
std::string FindStorageMethodName(uint32_t raw_value)
{
const auto* e = FindStorageMethod(raw_value);
return e ? e->display_name : MakeUnknownUIntName("UNKNOWN_STORAGE_METHOD", raw_value);
}
std::string FindStorageMethodFlagsName(uint32_t raw_value)
{
std::vector<std::string> parts;
if (raw_value & ID_SERIES_METHOD_VALUES)
parts.emplace_back("VALUES");
if (raw_value & ID_SERIES_METHOD_SCALED)
parts.emplace_back("SCALED");
if (raw_value & ID_SERIES_METHOD_INCREMENT)
parts.emplace_back("INCREMENT");
if (parts.empty())
return "UNKNOWN_STORAGE_METHOD(" + std::to_string(raw_value) + ")";
std::ostringstream oss;
for (size_t i = 0; i < parts.size(); ++i)
{
if (i > 0) oss << "|";
oss << parts[i];
}
return oss.str();
}
std::string FindTriggerMethodName(uint32_t raw_value)
{
const auto* e = FindTriggerMethod(raw_value);
return e ? e->display_name : MakeUnknownUIntName("UNKNOWN_TRIGGER_METHOD", raw_value);
}
// ============================================================================
// GUID registry
// ============================================================================
GuidSemanticRegistry::GuidSemanticRegistry()
{
auto add_table = [this](const GuidSemanticEntry* table, std::size_t n)
{
for (std::size_t i = 0; i < n; ++i)
{
const GuidSemanticEntry& e = table[i];
map_.insert({ Key{ e.field, e.raw_guid }, &e });
}
};
add_table(kQuantityTypeTable, kQuantityTypeTableSize);
add_table(kValueTypeTable, kValueTypeTableSize);
add_table(kQuantityCharacteristicTable, kQuantityCharacteristicTableSize);
add_table(kDisturbanceCategoryTable, kDisturbanceCategoryTableSize);
}
const GuidSemanticEntry* GuidSemanticRegistry::Find(GuidSemanticField field, const GUID& raw_guid) const
{
auto it = map_.find(Key{ field, raw_guid });
if (it == map_.end())
return nullptr;
return it->second;
}
std::string GuidSemanticRegistry::FindName(GuidSemanticField field, const GUID& raw_guid, const char* fallback) const
{
const auto* e = Find(field, raw_guid);
if (e)
return e->display_name;
return fallback ? std::string(fallback) : GuidToString(raw_guid);
}
const GuidSemanticRegistry& GetGuidSemanticRegistry()
{
static GuidSemanticRegistry registry;
return registry;
}
// ============================================================================
// helper
// ============================================================================
bool IsQuantityTypeValueLog(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_QT_VALUELOG);
}
bool IsValueTypeTime(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_SERIES_VALUE_TYPE_TIME);
}
bool IsValueTypeVal(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_SERIES_VALUE_TYPE_VAL);
}
bool IsValueTypeMin(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_SERIES_VALUE_TYPE_MIN);
}
bool IsValueTypeMax(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_SERIES_VALUE_TYPE_MAX);
}
bool IsValueTypeAvg(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_SERIES_VALUE_TYPE_AVG);
}
bool IsValueTypeInterval(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_SERIES_VALUE_TYPE_INTERVAL);
}
bool IsCharacteristicFrequency(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_QC_FREQUENCY);
}
bool IsCharacteristicRms(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_QC_RMS);
}
bool IsCharacteristicTotalThd(const GUID& raw_guid)
{
return GuidEqual(raw_guid, ID_QC_TOTAL_THD) || GuidEqual(raw_guid, ID_QC_TOTAL_THD_RMS);
}
bool IsUnitHertz(uint32_t raw_value)
{
return raw_value == ID_QU_HERTZ;
}
bool IsTriggerPeriodicStats(uint32_t raw_value)
{
return raw_value == ID_TRIGGER_METH_PERIODIC_STATS;
}
} // namespace pqdif_sem

View File

@@ -0,0 +1,347 @@
#pragma once
#include <cstdint>
#include <cstddef>
#include <string>
#include <unordered_map>
#include <vector>
#include <cstring>
#include "pqdif/include/pqdif_ph.h"
#include "pqdif/include/pqdif_id.h"
namespace pqdif_sem
{
// ============================================================================
// ˵<><CBB5>
// ----------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>ֻ<EFBFBD><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͡<EFBFBD><CDA1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD><D7B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFB1A3>ԭʼ<D4AD>ֶ<EFBFBD>ֵ<EFBFBD><D6B5>UINT4 / GUID<49><44>
// ӳ<><D3B3><EFBFBD><EFBFBD>ͨ<EFBFBD><CDA8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ԭʼֵ<CABC><D6B5><EFBFBD>ͳɡ<CDB3><C9A1><EFBFBD>׼<EFBFBD><D7BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD> + <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ============================================================================
// ------------------------------
// GUID <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ------------------------------
inline bool GuidEqual(const GUID& a, const GUID& b)
{
return std::memcmp(&a, &b, sizeof(GUID)) == 0;
}
struct GuidHash
{
std::size_t operator()(const GUID& g) const noexcept
{
const unsigned char* p = reinterpret_cast<const unsigned char*>(&g);
std::size_t h = 1469598103934665603ull; // FNV-1a <20><><EFBFBD><EFBFBD>
for (std::size_t i = 0; i < sizeof(GUID); ++i)
{
h ^= static_cast<std::size_t>(p[i]);
h *= 1099511628211ull;
}
return h;
}
};
std::string GuidToString(const GUID& g);
// ============================================================================
// һ<><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ID ö<>٣<EFBFBD><D9A3><EFBFBD>Դ<EFBFBD><D4B4>PDF <20><> B.2 / B.3 / B.4<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pqdif_id.h <20><><EFBFBD>к궨<D0BA>
// ============================================================================
// ------------------------------
// 1) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tagPhaseID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UINT4
// <20><>Դ<EFBFBD><D4B4>PDF <20><> B.2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>pqdif/include/pqdif_id.h
// ------------------------------
enum class PhaseId : uint32_t
{
None = ID_PHASE_NONE,
AN = ID_PHASE_AN,
BN = ID_PHASE_BN,
CN = ID_PHASE_CN,
NG = ID_PHASE_NG,
AB = ID_PHASE_AB,
BC = ID_PHASE_BC,
CA = ID_PHASE_CA,
RES = ID_PHASE_RES,
NET = ID_PHASE_NET,
Total = ID_PHASE_TOTAL,
LnAve = ID_PHASE_LN_AVE,
LlAve = ID_PHASE_LL_AVE,
Worst = ID_PHASE_WORST,
Plus = ID_PHASE_PLUS,
Minus = ID_PHASE_MINUS,
General1 = ID_PHASE_GENERAL_1,
General2 = ID_PHASE_GENERAL_2,
General3 = ID_PHASE_GENERAL_3,
General4 = ID_PHASE_GENERAL_4,
General5 = ID_PHASE_GENERAL_5,
General6 = ID_PHASE_GENERAL_6,
General7 = ID_PHASE_GENERAL_7,
General8 = ID_PHASE_GENERAL_8,
General9 = ID_PHASE_GENERAL_9,
General10 = ID_PHASE_GENERAL_10,
General11 = ID_PHASE_GENERAL_11,
General12 = ID_PHASE_GENERAL_12,
General13 = ID_PHASE_GENERAL_13,
General14 = ID_PHASE_GENERAL_14,
General15 = ID_PHASE_GENERAL_15,
General16 = ID_PHASE_GENERAL_16
};
// ------------------------------
// 2) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>tagQuantityMeasuredID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UINT4
// <20><>Դ<EFBFBD><D4B4>PDF <20><> B.2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>pqdif/include/pqdif_id.h
// ע<><EFBFBD><E2A3BA><EFBFBD><EFBFBD>û<EFBFBD><C3BB> Frequency<63><79>Ƶ<EFBFBD><C6B5><EFBFBD><EFBFBD> characteristic <20><><EFBFBD>
// ------------------------------
enum class QuantityMeasuredId : uint32_t
{
None = ID_QM_NONE,
Voltage = ID_QM_VOLTAGE,
Current = ID_QM_CURRENT,
Power = ID_QM_POWER,
Energy = ID_QM_ENERGY,
Temperature = ID_QM_TEMPERATURE,
Pressure = ID_QM_PRESSURE,
Charge = ID_QM_CHARGE,
EField = ID_QM_EFIELD,
MField = ID_QM_MFIELD,
Velocity = ID_QM_VELOCITY,
Bearing = ID_QM_BEARING,
Force = ID_QM_FORCE,
Torque = ID_QM_TORQUE,
Position = ID_QM_POSITION,
FluxLinkage = ID_QM_FLUXLINKAGE,
FluxDensity = ID_QM_FLUXDENSITY,
Status = ID_QM_STATUS
};
// ------------------------------
// 3) <20><>λ<EFBFBD><CEBB>tagQuantityUnitsID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UINT4
// <20><>Դ<EFBFBD><D4B4>PDF <20><> B.2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>pqdif/include/pqdif_id.h
// ------------------------------
enum class QuantityUnitsId : uint32_t
{
None = ID_QU_NONE,
Timestamp = ID_QU_TIMESTAMP,
Seconds = ID_QU_SECONDS,
Cycles = ID_QU_CYCLES,
Volts = ID_QU_VOLTS,
Amps = ID_QU_AMPS,
VA = ID_QU_VA,
Watts = ID_QU_WATTS,
Vars = ID_QU_VARS,
Ohms = ID_QU_OHMS,
Siemens = ID_QU_SIEMENS,
VoltsPerAmp = ID_QU_VOLTSPERAMP,
Joules = ID_QU_JOULES,
Hertz = ID_QU_HERTZ,
Celcius = ID_QU_CELCIUS,
Degrees = ID_QU_DEGREES,
Db = ID_QU_DB,
Percent = ID_QU_PERCENT,
PerUnit = ID_QU_PERUNIT,
Samples = ID_QU_SAMPLES,
VarHours = ID_QU_VARHOURS,
WattHours = ID_QU_WATTHOURS,
VaHours = ID_QU_VAHOURS,
Mps = ID_QU_MPS,
Mph = ID_QU_MPH,
Bars = ID_QU_BARS,
Pascals = ID_QU_PASCALS,
Newtons = ID_QU_NEWTONS,
NewtonMeters = ID_QU_NEWTONMETERS,
Rpm = ID_QU_RPM,
RadPerSec = ID_QU_RADPERSEC,
Meters = ID_QU_METERS,
WeberTurns = ID_QU_WEBERTURNS,
Teslas = ID_QU_TESLAS,
Webers = ID_QU_WEBERS,
VoltsPerVolt = ID_QU_VOLTSPERVOLT,
AmpsPerAmp = ID_QU_AMPSPERAMP,
AmpsPerVolt = ID_QU_AMPSPERVOLT
};
// ------------------------------
// 4) <20><><EFBFBD>д洢<D0B4><E6B4A2>ʽ<EFBFBD><CABD>tagStorageMethodID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UINT4
// <20><>Դ<EFBFBD><D4B4>PDF <20><> B.2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>pqdif/include/pqdif_id.h
// ------------------------------
enum class StorageMethodId : uint32_t
{
Values = ID_SERIES_METHOD_VALUES,
Scaled = ID_SERIES_METHOD_SCALED,
Increment = ID_SERIES_METHOD_INCREMENT
};
// ------------------------------
// 5) <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><CABD>tagTriggerMethodID<49><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> UINT4
// <20><>Դ<EFBFBD><D4B4>PDF <20><> B.3 / B.4<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD><EFBFBD>pqdif/include/pqdif_id.h
// ------------------------------
enum class TriggerMethodId : uint32_t
{
None = ID_TRIGGER_METH_NONE,
Channel = ID_TRIGGER_METH_CHANNEL,
Periodic = ID_TRIGGER_METH_PERIODIC,
External = ID_TRIGGER_METH_EXTERNAL,
PeriodicStats = ID_TRIGGER_METH_PERIODIC_STATS
};
// ============================================================================
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
// ============================================================================
struct UIntSemanticEntry
{
uint32_t raw_value; // ԭʼ UINT4 ֵ
const char* standard_name; // <20><>׼<EFBFBD><D7BC><>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ID_PHASE_AN
const char* display_name; // <20><><EFBFBD><EFBFBD>չʾ<D5B9><CABE>
const char* source_tag; // <20><>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD>׼<EFBFBD>ֶΣ<D6B6><CEA3><EFBFBD><EFBFBD><EFBFBD> tagPhaseID
const char* comment; // <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
};
// ============================================================================
// <20><><EFBFBD><EFBFBD>GUID <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ----------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> GUID ֵ<><D6B5><EFBFBD>ֳ<EFBFBD><D6B3><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD> pqdif_id.h <20><><EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>ÿһ<C3BF><EFBFBD>ܻ<EFBFBD><DCBB>ݵ<EFBFBD><DDB5><EFBFBD><EFBFBD><EFBFBD> pqdif ͷ<>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD>
// ============================================================================
enum class GuidSemanticField
{
QuantityType, // tagQuantityTypeID
ValueType, // tagValueTypeID
QuantityCharacteristic, // tagQuantityCharacteristicID
DisturbanceCategory // tagDisturbanceCategoryID
};
struct GuidSemanticEntry
{
GUID raw_guid; // ԭʼ GUID ֵ
GuidSemanticField field; // <20><><EFBFBD><EFBFBD><EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD>
const char* standard_name; // <20><>׼<EFBFBD><D7BC><>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> ID_QT_VALUELOG
const char* display_name; // <20><><EFBFBD><EFBFBD>չʾ<D5B9><CABE>
const char* source_tag; // <20><>Ӧ<EFBFBD>ı<EFBFBD>׼<EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD>
const char* comment; // <20><><EFBFBD><EFBFBD>˵<EFBFBD><CBB5>
};
// ============================================================================
// <20>ġ<EFBFBD><C4A1>̶<EFBFBD><CCB6><EFBFBD>̬<EFBFBD><CCAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ݹ̶<DDB9><CCB6><EFBFBD><EFBFBD><EFBFBD>Դ<EFBFBD>̶<EFBFBD><CCB6><EFBFBD>registry ֻ<>Dz<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ============================================================================
extern const UIntSemanticEntry kPhaseTable[];
extern const std::size_t kPhaseTableSize;
extern const UIntSemanticEntry kQuantityMeasuredTable[];
extern const std::size_t kQuantityMeasuredTableSize;
extern const UIntSemanticEntry kQuantityUnitsTable[];
extern const std::size_t kQuantityUnitsTableSize;
extern const UIntSemanticEntry kStorageMethodTable[];
extern const std::size_t kStorageMethodTableSize;
extern const UIntSemanticEntry kTriggerMethodTable[];
extern const std::size_t kTriggerMethodTableSize;
extern const GuidSemanticEntry kQuantityTypeTable[];
extern const std::size_t kQuantityTypeTableSize;
extern const GuidSemanticEntry kValueTypeTable[];
extern const std::size_t kValueTypeTableSize;
extern const GuidSemanticEntry kQuantityCharacteristicTable[];
extern const std::size_t kQuantityCharacteristicTableSize;
extern const GuidSemanticEntry kDisturbanceCategoryTable[];
extern const std::size_t kDisturbanceCategoryTableSize;
// ============================================================================
// <20><EFBFBD><E5A1A2>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD>
// ============================================================================
const UIntSemanticEntry* FindUIntSemantic(
const UIntSemanticEntry* table,
std::size_t table_size,
uint32_t raw_value);
const UIntSemanticEntry* FindPhase(uint32_t raw_value);
const UIntSemanticEntry* FindQuantityMeasured(uint32_t raw_value);
const UIntSemanticEntry* FindQuantityUnits(uint32_t raw_value);
const UIntSemanticEntry* FindStorageMethod(uint32_t raw_value);
const UIntSemanticEntry* FindTriggerMethod(uint32_t raw_value);
std::string FindPhaseName(uint32_t raw_value);
std::string FindQuantityMeasuredName(uint32_t raw_value);
std::string FindQuantityUnitsName(uint32_t raw_value);
std::string FindStorageMethodName(uint32_t raw_value);
std::string FindStorageMethodFlagsName(uint32_t raw_value);
std::string FindTriggerMethodName(uint32_t raw_value);
// ============================================================================
// <20><><EFBFBD><EFBFBD>GUID ע<><D7A2><EFBFBD><EFBFBD>
// ----------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD><EFBFBD>ݹ̶<DDB9><CCB6><EFBFBD>registry ֻ<>ǰѹ̶<D1B9><CCB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɿ<EFBFBD><C9BF>ٲ<EFBFBD>ѯ<EFBFBD><D1AF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ============================================================================
class GuidSemanticRegistry
{
public:
GuidSemanticRegistry();
const GuidSemanticEntry* Find(GuidSemanticField field, const GUID& raw_guid) const;
std::string FindName(GuidSemanticField field, const GUID& raw_guid, const char* fallback = "UNKNOWN_GUID") const;
private:
struct Key
{
GuidSemanticField field;
GUID guid;
};
struct KeyHash
{
std::size_t operator()(const Key& k) const noexcept
{
std::size_t h1 = std::hash<int>{}(static_cast<int>(k.field));
std::size_t h2 = GuidHash{}(k.guid);
return h1 ^ (h2 << 1);
}
};
struct KeyEq
{
bool operator()(const Key& a, const Key& b) const noexcept
{
return a.field == b.field && GuidEqual(a.guid, b.guid);
}
};
std::unordered_map<Key, const GuidSemanticEntry*, KeyHash, KeyEq> map_;
};
const GuidSemanticRegistry& GetGuidSemanticRegistry();
// ============================================================================
// <20>ߡ<EFBFBD>ͳ<EFBFBD><CDB3>ӳ<EFBFBD><EFBFBD><E4B3A3> helper
// ----------------------------------------------------------------------------
// <20><><EFBFBD><EFBFBD>ֻ<EFBFBD>š<EFBFBD><C5A1><EFBFBD><EFBFBD><EFBFBD>ȷ<EFBFBD><C8B7>Դ<EFBFBD>Ҷ<EFBFBD>ͳ<EFBFBD><CDB3>ӳ<EFBFBD><EFBFBD>á<EFBFBD><C3A1><EFBFBD><EFBFBD>жϡ<D0B6>
// <20><><EFBFBD><EFBFBD><EFBFBD>²<EFBFBD><C2B2><EFBFBD> helper<65><72>
// ============================================================================
bool IsQuantityTypeValueLog(const GUID& raw_guid);
bool IsValueTypeTime(const GUID& raw_guid);
bool IsValueTypeVal(const GUID& raw_guid);
bool IsValueTypeMin(const GUID& raw_guid);
bool IsValueTypeMax(const GUID& raw_guid);
bool IsValueTypeAvg(const GUID& raw_guid);
bool IsValueTypeInterval(const GUID& raw_guid);
bool IsCharacteristicFrequency(const GUID& raw_guid);
bool IsCharacteristicRms(const GUID& raw_guid);
bool IsCharacteristicTotalThd(const GUID& raw_guid);
bool IsUnitHertz(uint32_t raw_value);
bool IsTriggerPeriodicStats(uint32_t raw_value);
} // namespace pqdif_sem#pragma once

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,768 @@
#pragma once
#include <ctime>
#include <cstddef>
#include <complex>
#include <map>
#include <string>
#include <vector>
#include "pqdif/include/pqdif_ph.h"
// ============================
// 新版:完整 PQDIF 逻辑结构
// 说明:
// 1) 该结构尽量忠实表达 PQDIF 的“文件 -> 记录 -> 定义/实例 -> 数组值”关系;
// 2) 后续所有映射、归并、按时刻整合都应该基于这些结构做;
// 3) 对暂未显式建模的标签,统一进入 extra_tags避免丢失信息。
// ============================
using PqdifExtraTagMap = std::map<std::string, std::string>;
// GUID 及其可读名称
struct PqdifGuidValue
{
GUID value{}; // 原始 GUID 值
std::string symbolic_name; // 通过 PQDIF 信息表解析出的标准名,如 tagPhaseID / ID_QT_VALUELOG 等
};
// PQDIF 原始时间戳
struct PqdifTimestampValue
{
UINT4 day = 0; // 自 1900-01-01 起的天数PQDIF 原始 day 字段
double second = 0.0; // 当天起算的秒PQDIF 原始 sec 字段
time_t unix_time = 0; // 转换后的 Unix 时间戳,便于上层使用
std::string text; // 格式化后的本地时间文本,便于调试和日志输出
};
// 记录头信息
struct PqdifRecordHeaderInfo
{
long record_index = -1; // 本记录在文件中的顺序索引
long file_position = 0; // 记录头在文件中的偏移
PqdifGuidValue record_type; // 记录类型,如 tagContainer / tagRecDataSource / tagRecObservation
long header_size = 0; // 记录头字节数
long data_size = 0; // 记录体字节数
long next_record_position = 0; // 下一条记录偏移
unsigned int checksum = 0; // 记录校验值
};
// 通用数组值容器:用于保存 PQDIF 向量/序列的真正数组内容
struct PqdifValueArray
{
int physical_type = -1; // PQDIF 物理类型 ID例如 REAL8 / UINT4 / TIMESTAMPPQDIF
long count = 0; // 数组点数
std::vector<bool> bool_values; // 布尔数组
std::vector<long long> int_values; // 有符号整数数组
std::vector<unsigned long long> uint_values; // 无符号整数数组
std::vector<double> real_values; // 浮点数组,最常见的统计值/波形值
std::vector<std::complex<double>> complex_values; // 复数数组
std::vector<PqdifTimestampValue> timestamp_values; // 时间戳数组
std::vector<PqdifGuidValue> guid_values; // GUID 数组
std::vector<std::string> text_values; // 字符串数组CHAR1/CHAR2
};
// Container / General Record文件级元数据
struct PqdifContainerRecord
{
PqdifRecordHeaderInfo header; // 记录头
std::vector<unsigned int> version_info; // tagVersionInfo格式版本号数组
std::string file_name; // tagFileName原始文件名
PqdifTimestampValue creation_time; // tagCreation文件创建时间
PqdifTimestampValue last_saved_time; // tagLastSaved最后保存时间
unsigned int times_saved = 0; // tagTimesSaved保存次数
std::string language; // tagLanguage语言
std::string title; // tagTitle标题
std::string subject; // tagSubject主题
std::string author; // tagAuthor作者
std::string keywords; // tagKeywords关键字
std::string comments; // tagComments备注
std::string last_saved_by; // tagLastSavedBy最后保存者
std::string application; // tagApplication生成软件
PqdifGuidValue compression_style_id; // tagCompressionStyleID压缩风格
unsigned int compression_algorithm_id = 0; // tagCompressionAlgorithmID压缩算法
unsigned int compression_checksum = 0; // tagCompressionChecksum压缩校验值
std::string owner; // tagOwner所有者
std::string copyright; // tagCopyright版权
std::string trademarks; // tagTrademarks商标
std::string notes; // tagNotes附加说明
std::string address1; // tagAddress1地址行 1
std::string address2; // tagAddress2地址行 2
std::string city; // tagCity城市
std::string state; // tagState州/省
std::string postal_code; // tagPostalCode邮编
std::string country; // tagCountry国家
std::string phone_voice; // tagPhoneVoice电话
std::string phone_fax; // tagPhoneFAX传真
std::string email; // tagEmail邮箱
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// Series Definition序列定义描述“这一列是什么”
struct PqdifSeriesDefinition
{
int series_def_index = -1; // 序列定义在所属通道定义中的顺序索引
unsigned int quantity_units_id = 0; // tagQuantityUnitsID单位 ID
PqdifGuidValue quantity_characteristic_id; // tagQuantityCharacteristicID特征量 ID
PqdifGuidValue value_type_id; // tagValueTypeID值类型 ID例如 TIME / AVG / MAX / MIN / VAL
unsigned int storage_method_id = 0; // tagStorageMethodID序列存储方式
unsigned int significant_digits_id = 0; // tagQuantitySignificantDigitsID有效位定义
double quantity_resolution = 0.0; // tagQuantityResolutionID / 解析出的分辨率
double nominal_quantity = 0.0; // tagSeriesNominalQuantity标称值
std::string value_type_name; // tagValueTypeName值类型显示名
unsigned int hint_greek_prefix_id = 0; // tagHintGreekPrefixID显示前缀提示
unsigned int hint_preferred_units_id = 0; // tagHintPreferredUnitsID优选单位提示
unsigned int hint_default_display_id = 0; // tagHintDefaultDisplayID默认显示方式提示
double prob_interval = 0.0; // tagProbInterval概率间隔
double prob_percentile = 0.0; // tagProbPercentile概率百分位
PqdifTimestampValue effective_time; // tagEffective定义生效时间
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// Channel Definition通道定义描述“这个通道测什么”
struct PqdifChannelDefinition
{
int channel_def_index = -1; // 通道定义在数据源中的顺序索引
std::string channel_name; // tagChannelName通道名称
unsigned int phase_id = 0; // tagPhaseID相别
std::string other_channel_identifier; // tagOtherChannelIdentifier附加通道标识
std::string group_name; // tagGroupName组名称
PqdifGuidValue quantity_type_id; // tagQuantityTypeID量类型如 VALUELOG / PHASOR
unsigned int quantity_measured_id = 0; // tagQuantityMeasuredID被测量对象如电压/电流/频率)
unsigned int physical_channel = 0; // tagPhysicalChannel物理通道编号
std::string quantity_name; // tagQuantityName自定义量名称
int primary_series_index = -1; // tagPrimarySeriesIdx主序列索引
std::vector<PqdifSeriesDefinition> series_definitions; // 该通道下的全部序列定义
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// Data Source Record数据源定义描述设备和通道体系
struct PqdifDataSourceRecord
{
PqdifRecordHeaderInfo header; // 记录头
int data_source_index = -1; // 在文件中解析出的数据源顺序索引
long record_index = -1; // 对应文件记录索引,便于关联 Observation
PqdifGuidValue data_source_type_id; // tagDataSourceTypeID数据源类型
PqdifGuidValue vendor_id; // tagVendorID厂商 ID
PqdifGuidValue equipment_id; // tagEquipmentID设备型号 ID
std::string custom_source_info; // tagCustomSourceInfo扩展来源信息
PqdifGuidValue instrument_type_id; // tagInstrumentTypeID仪器类型
std::string instrument_model_name; // tagInstrumentModelName仪器型号名称
std::string instrument_model_number; // tagInstrumentModelNumber仪器型号编号
std::string serial_number; // tagSerialNumberDS序列号
std::string version; // tagVersionDS版本号
std::string name; // tagNameDS设备名称
std::string owner; // tagOwnerDS设备归属
std::string location; // tagLocationDS安装位置
std::string time_zone; // tagTimeZoneDS时区文本
std::string coordinates; // tagCoordinatesDS坐标信息
std::vector<PqdifChannelDefinition> channel_definitions; // 数据源下的全部通道定义
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// Monitor Settings 中单通道的配置
struct PqdifChannelSetting
{
int channel_setting_index = -1; // 通道设置在监测设置记录中的顺序索引
int channel_def_index = -1; // tagChannelDefnIdx关联的数据源通道定义索引
unsigned int trigger_type_id = 0; // tagTriggerTypeID触发类型
double full_scale = 0.0; // tagFullScale满量程
double noise_floor = 0.0; // tagNoiseFloor噪声底
PqdifValueArray trigger_shape_param; // tagTriggerShapeParam触发曲线/参数数组
unsigned int xd_transformer_type_id = 0; // tagXDTransformerTypeID互感器类型
double xd_system_side_ratio = 0.0; // tagXDSystemSideRatio一次侧变比
double xd_monitor_side_ratio = 0.0; // tagXDMonitorSideRatio监测侧变比
PqdifValueArray xd_frequency_response; // tagXDFrequencyResponse频率响应数组
double cal_time_skew = 0.0; // tagCalTimeSkew校准时延
double cal_offset = 0.0; // tagCalOffset校准偏移
double cal_ratio = 0.0; // tagCalRatio校准比例
bool cal_must_use_arcal = false; // tagCalMustUseARCal是否必须使用校准曲线
PqdifValueArray cal_applied; // tagCalApplied校准应用值数组
PqdifValueArray cal_recorded; // tagCalRecorded校准记录值数组
double trigger_high_high = 0.0; // tagTriggerHighHigh高高阈值
double trigger_high = 0.0; // tagTriggerHigh高阈值
double trigger_low = 0.0; // tagTriggerLow低阈值
double trigger_low_low = 0.0; // tagTriggerLowLow低低阈值
double trigger_deadband = 0.0; // tagTriggerDeadband死区
double trigger_rate = 0.0; // tagTriggerRate触发速率
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// Monitor Settings Record监测装置配置
struct PqdifMonitorSettingsRecord
{
PqdifRecordHeaderInfo header; // 记录头
int settings_index = -1; // 在文件中解析出的监测设置顺序索引
long record_index = -1; // 对应文件记录索引,便于关联 Observation
PqdifTimestampValue effective_time; // tagEffective配置生效时间
PqdifTimestampValue time_installed; // tagTimeInstalled安装时间
PqdifTimestampValue time_removed; // tagTimeRemoved拆除时间
bool use_calibration = false; // tagUseCalibration是否使用校准
bool use_transducer = false; // tagUseTransducer是否使用传感器/互感器
double nominal_frequency = 0.0; // tagNominalFrequency额定频率
unsigned int physical_connection = 0; // tagSettingPhysicalConnection物理接线方式
double nominal_voltage = 0.0; // tagNominalVoltage额定电压
bool is_pcc = false; // tagIsPCC是否为 PCC 点
std::vector<PqdifChannelSetting> channel_settings; // 各通道的监测配置
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// Observation 中单个序列实例:保存某一次观测里的一个真实数组
struct PqdifSeriesInstance
{
int series_instance_index = -1; // 序列实例在通道实例中的顺序索引
int series_def_index = -1; // 关联的数据源序列定义索引(通常与定义层顺序一致)
unsigned int quantity_units_id = 0; // tagQuantityUnitsID本实例对应的单位 ID
PqdifGuidValue quantity_characteristic_id; // tagQuantityCharacteristicID本实例特征量 ID
PqdifGuidValue value_type_id; // tagValueTypeID本实例值类型 ID
long series_base_type = -1; // 当前库暴露的底层序列物理类型
double series_base_quantity = 0.0; // tagSeriesBaseQuantity序列基值
double scale = 1.0; // tagSeriesScale缩放系数
double offset = 0.0; // tagSeriesOffset偏移量
double nominal_quantity = 0.0; // 关联定义层解析出的标称量
unsigned int significant_digits_id = 0; // 关联定义层解析出的有效位配置
double quantity_resolution = 0.0; // 关联定义层解析出的分辨率
int share_channel_index = -1; // tagSeriesShareChannelIdx共享通道索引
int share_series_index = -1; // tagSeriesShareSeriesIdx共享序列索引
PqdifValueArray values; // tagSeriesValues真正的数组值
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// Observation 中单个通道实例:保存某一次观测里的一个真实通道块
struct PqdifChannelInstance
{
int channel_instance_index = -1; // 通道实例在观测中的顺序索引
int channel_def_index = -1; // 关联的数据源通道定义索引
std::string channel_name; // 从 Observation 读出的通道名
unsigned int phase_id = 0; // 相别
PqdifGuidValue quantity_type_id; // 量类型
unsigned int quantity_measured_id = 0; // 被测量对象
int primary_series_index = -1; // 主序列索引
double charact_duration = 0.0; // tagCharactDuration特征持续时间
double charact_magnitude = 0.0; // tagCharactMagnitude特征幅值
double charact_frequency = 0.0; // tagCharactFrequency特征频率
double channel_frequency = 0.0; // tagChannelFrequency通道频率
int channel_group_id = 0; // tagChannelGroupID通道分组
std::vector<PqdifSeriesInstance> series_instances; // 该通道实例下的所有序列实例
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// Observation Record一次真实观测
struct PqdifObservationRecord
{
PqdifRecordHeaderInfo header; // 记录头
int observation_index = -1; // 在文件中解析出的观测顺序索引
long record_index = -1; // 对应文件记录索引
int related_data_source_index = -1; // 该观测关联的数据源顺序索引
long related_data_source_record_index = -1; // 该观测关联的数据源记录索引
int related_settings_index = -1; // 该观测关联的监测设置顺序索引
long related_settings_record_index = -1; // 该观测关联的监测设置记录索引
std::string observation_name; // tagObservationName观测名称
PqdifTimestampValue time_create; // tagTimeCreate观测记录创建时间
PqdifTimestampValue time_start; // tagTimeStart观测起始时间
unsigned int trigger_method_id = 0; // tagTriggerMethodID触发方式
PqdifTimestampValue time_triggered; // tagTimeTriggered触发时刻
std::vector<int> channel_trigger_indexes; // tagChannelTriggerIdx触发通道索引数组
unsigned int observation_serial = 0; // tagObservationSerial观测序号
unsigned int observation_aggregation_serial = 0; // tagObservationAggregationSerial聚合序号
PqdifGuidValue disturbance_category_id; // tagDisturbanceCategoryID扰动分类
std::vector<PqdifChannelInstance> channel_instances; // 本次观测中的所有通道实例
PqdifExtraTagMap extra_tags; // 当前结构未单独建模但已读出的标签
};
// 文件级完整逻辑对象
struct PqdifLogicalFile
{
std::vector<PqdifRecordHeaderInfo> record_headers; // 文件中所有记录的头信息,保留顺序
std::vector<PqdifContainerRecord> containers; // Container / General 记录,一般只有一个
std::vector<PqdifDataSourceRecord> data_sources; // 全部数据源记录
std::vector<PqdifMonitorSettingsRecord> monitor_settings; // 全部监测设置记录
std::vector<PqdifObservationRecord> observations; // 全部观测记录
};
// ============================
// 统计识别与同一时间聚合层
// 说明:
// 1) 这一层只服务于“从完整 PQDIF 结构中识别目标统计指标并按时间聚合”;
// 2) 当前阶段先不做 tagPqData_Float 映射;
// 3) 当前阶段只处理“筛选出的统计类 observation”其他 observation 暂不参与识别。
// ============================
// 解析得到的接线方式
// 用于区分星型 / 角型 两套指标规则。
enum class ParsedConnectionKind
{
Unknown = 0, // 未知 / 无法确认
Wye, // 星型 / Y
Delta // 角型 / Δ
};
// 当前支持的业务指标 ID
// 后续如果新增指标,只需要继续往这里加枚举,并在 cpp 里的识别规则补充即可。
enum class StatMetricId
{
Unknown = 0,
// 相电压有效值
UaRms,
UbRms,
UcRms,
// 相电流有效值
IaRms,
IbRms,
IcRms,
// 线电压有效值
UabRms,
UbcRms,
UcaRms,
// 相电压偏差
UaDeviation,
UbDeviation,
UcDeviation,
// 线电压偏差
UabDeviation,
UbcDeviation,
UcaDeviation,
// 频率
Frequency,
// 频率偏差
FrequencyDeviation,
// 电压序分量
UZeroSeq, // 电压零序分量
UNegSeq, // 电压负序分量
UPosSeq, // 电压正序分量
// 电压负序不平衡,通常对应 S2/S1单位可能为 % 或 pu
UNegSeqUnbalance,
// 电流序分量
IZeroSeq, // 电流零序分量
INegSeq, // 电流负序分量
IPosSeq, // 电流正序分量
// 电流负序不平衡,通常对应 S2/S1单位可能为 % 或 pu
INegSeqUnbalance,
// 功率类:三相/总有功、无功、视在功率
PaPower,
PbPower,
PcPower,
PTotalPower,
QaPower,
QbPower,
QcPower,
QTotalPower,
SaPower,
SbPower,
ScPower,
STotalPower,
// 功率因数类:三相/总功率因数、三相/总基波功率因数
PFa,
PFb,
PFc,
PFTotal,
FundPFa,
FundPFb,
FundPFc,
FundPFTotal,
// 电压变动幅值 DVC/dV/V三相与线电压
UaDvc,
UbDvc,
UcDvc,
UabDvc,
UbcDvc,
UcaDvc,
// 闪变:三相和线电压短闪 Pst、长闪 Plt
UaPst,
UbPst,
UcPst,
UabPst,
UbcPst,
UcaPst,
UaPlt,
UbPlt,
UcPlt,
UabPlt,
UbcPlt,
UcaPlt,
// 基波功率:三相/总有功、无功、视在基波功率
PaFundPower,
PbFundPower,
PcFundPower,
PTotalFundPower,
QaFundPower,
QbFundPower,
QcFundPower,
QTotalFundPower,
SaFundPower,
SbFundPower,
ScFundPower,
STotalFundPower,
// 基波有效值与基波相角:三相电压、三相电流、线电压
UaFundRms,
UbFundRms,
UcFundRms,
UaFundAngle,
UbFundAngle,
UcFundAngle,
IaFundRms,
IbFundRms,
IcFundRms,
IaFundAngle,
IbFundAngle,
IcFundAngle,
UabFundRms,
UbcFundRms,
UcaFundRms,
UabFundAngle,
UbcFundAngle,
UcaFundAngle,
// 总谐波畸变率 THD三相电压、三相电流、线电压
UaThd,
UbThd,
UcThd,
IaThd,
IbThd,
IcThd,
UabThd,
UbcThd,
UcaThd,
// 谐波/间谐波类动态指标范围。
//
// 不再为 2-50 次谐波逐项声明 UaHarm02、UaHarm03 ... UcHarm50
// 而是用“指标族基址 + 相别 + 次数”的方式动态构造。这样后续新增
// 电流谐波、间谐波、谐波含有率等指标时,不需要继续堆大量 enum 项。
//
// 当前已启用:
// VoltageHarmonicUaBase + order => UaHarmXX, order=2..50
// VoltageHarmonicUbBase + order => UbHarmXX, order=2..50
// VoltageHarmonicUcBase + order => UcHarmXX, order=2..50
// 预留区间:
// CurrentHarmonic* 后续电流谐波
// VoltageInterharmonic* 后续电压间谐波
// CurrentInterharmonic* 后续电流间谐波
// 三相电压谐波 RMSorder=2..50
VoltageHarmonicUaBase = 10000,
VoltageHarmonicUbBase = 10100,
VoltageHarmonicUcBase = 10200,
// AB/BC/CA 线电压谐波 RMSorder=2..50
LineVoltageHarmonicUabBase = 10300,
LineVoltageHarmonicUbcBase = 10400,
LineVoltageHarmonicUcaBase = 10500,
// 三相电流谐波 RMSorder=2..50
CurrentHarmonicIaBase = 11000,
CurrentHarmonicIbBase = 11100,
CurrentHarmonicIcBase = 11200,
// 三相电压谐波相角order=2..50
VoltageHarmonicAngleUaBase = 12000,
VoltageHarmonicAngleUbBase = 12100,
VoltageHarmonicAngleUcBase = 12200,
// AB/BC/CA 线电压谐波相角order=2..50
LineVoltageHarmonicAngleUabBase = 12300,
LineVoltageHarmonicAngleUbcBase = 12400,
LineVoltageHarmonicAngleUcaBase = 12500,
// 三相电流谐波相角order=2..50
CurrentHarmonicAngleIaBase = 13000,
CurrentHarmonicAngleIbBase = 13100,
CurrentHarmonicAngleIcBase = 13200,
// 三相电压间谐波 RMSslot=0..49 表示 0.5..49.5 次
VoltageInterharmonicUaBase = 14000,
VoltageInterharmonicUbBase = 14100,
VoltageInterharmonicUcBase = 14200,
// AB/BC/CA 线电压间谐波 RMSslot=0..49 表示 0.5..49.5 次
LineVoltageInterharmonicUabBase = 14300,
LineVoltageInterharmonicUbcBase = 14400,
LineVoltageInterharmonicUcaBase = 14500,
// 三相电流间谐波 RMSslot=0..49 表示 0.5..49.5 次
CurrentInterharmonicIaBase = 15000,
CurrentInterharmonicIbBase = 15100,
CurrentInterharmonicIcBase = 15200,
// 谐波功率 2-50 次:三相/总 有功、无功、视在功率
HarmonicActivePowerPaBase = 16000,
HarmonicActivePowerPbBase = 16100,
HarmonicActivePowerPcBase = 16200,
HarmonicActivePowerTotalBase = 16300,
HarmonicReactivePowerQaBase = 16400,
HarmonicReactivePowerQbBase = 16500,
HarmonicReactivePowerQcBase = 16600,
HarmonicReactivePowerTotalBase = 16700,
HarmonicApparentPowerSaBase = 16800,
HarmonicApparentPowerSbBase = 16900,
HarmonicApparentPowerScBase = 17000,
HarmonicApparentPowerTotalBase = 17100,
// 谐波含有率 2-50 次:三相电压、三相电流、线电压
VoltageHarmonicRatioUaBase = 18000,
VoltageHarmonicRatioUbBase = 18100,
VoltageHarmonicRatioUcBase = 18200,
CurrentHarmonicRatioIaBase = 18300,
CurrentHarmonicRatioIbBase = 18400,
CurrentHarmonicRatioIcBase = 18500,
LineVoltageHarmonicRatioUabBase = 18600,
LineVoltageHarmonicRatioUbcBase = 18700,
LineVoltageHarmonicRatioUcaBase = 18800,
};
// 统计值类型:用于把 MIN / MAX / AVG / P95 装进同一时间桶。
enum class StatValueKind
{
Unknown = 0,
Min, // 最小值
Max, // 最大值
Avg, // 平均值
P95 // 95 值 / 百分位 95
};
// 指标质量状态。
// Normal 表示当前指标可正常使用;其他状态用于把“重复来源/全零/量程异常/缺失”显式暴露出来,
// 防止后续新增指标时继续出现静默覆盖或误识别。
enum class StatMetricQuality
{
Normal = 0,
AllZero,
DuplicateSource,
SuspiciousRange,
Missing
};
// 单个“已展开的统计样本点”
// 含义:某个统计 observation 中某个通道/某个序列/某个时间点的一条已还原工程值样本。
struct ExpandedStatPoint
{
time_t timestamp = 0; // 样本对应的绝对时刻
std::string timestamp_text; // 格式化后的时间文本,便于日志和调试
int observation_index = -1; // 来源 observation 索引
int channel_instance_index = -1; // 来源通道实例索引
int channel_def_index = -1; // 来源通道定义索引,便于排查同名/同相通道覆盖
int channel_group_id = 0; // 来源通道分组 ID部分厂家用它表示谐波次数
int channel_spectrum_order_hint = -1; // 当 group/base/nominal 缺失时,从同类通道实例顺序推导出的谐波次数 2..50
int channel_spectrum_block_offset = -1; // 同类通道实例块内偏移;用于排查厂家把谱线拆成多个通道但名称相同的情况
int channel_spectrum_block_size = 0; // 同类通道实例候选总数;用于日志确认是否是 2-50 次整组数据
int series_instance_index = -1; // 来源序列实例索引
int series_def_index = -1; // 来源序列定义索引,便于核查 MIN/MAX/AVG/P95 的定义来源
int sample_index = -1; // 序列内部样本点下标
std::string observation_name; // 来源 observation 名称
std::string channel_name; // 通道名称(如 V RMS A
std::string quantity_name; // 量名称(来自定义层)
unsigned int phase_id = 0; // 相别
PqdifGuidValue quantity_type_id; // 量类型VALUELOG 等)
unsigned int quantity_measured_id = 0; // 被测量对象Voltage / Current
unsigned int quantity_units_id = 0; // 单位 ID
PqdifGuidValue quantity_characteristic_id;// 特征量RMS / FREQUENCY
PqdifGuidValue value_type_id; // 值类型MIN / MAX / AVG / P95
double prob_percentile = 0.0; // 序列定义中的概率百分位(若有)
double series_base_quantity = 0.0; // 序列基值;部分 PQDIF 厂家会用它表达谐波次数
double nominal_quantity = 0.0; // 标称量;部分 PQDIF 厂家会用它表达谐波次数
double value = 0.0; // 工程值(已完成 scale/offset 还原)
ParsedConnectionKind connection_kind = ParsedConnectionKind::Unknown; // 当前文件识别出的接线方式
StatMetricId metric_id = StatMetricId::Unknown; // 该样本点识别出的业务指标
StatValueKind stat_kind = StatValueKind::Unknown; // 该样本点属于 MIN/MAX/AVG/P95 哪一种
bool matched_by_name_fallback = false; // 是否通过名称辅助规则匹配成功
};
// 某一个业务指标在某个时间点上的统计值集合
struct AggregatedStatValues
{
bool has_min = false; // 是否存在最小值
bool has_max = false; // 是否存在最大值
bool has_avg = false; // 是否存在平均值
bool has_p95 = false; // 是否存在 95 值
double min_value = 0.0; // 最小值
double max_value = 0.0; // 最大值
double avg_value = 0.0; // 平均值
double p95_value = 0.0; // 95 值
StatMetricQuality quality = StatMetricQuality::Normal; // 指标质量状态
std::string quality_reason; // 质量状态说明
int source_observation_index = -1; // 选中的来源 observation 索引
int source_channel_instance_index = -1; // 选中的来源通道实例索引
int source_series_instance_index = -1; // 最近一次写入该桶的来源序列实例索引
std::string source_channel_name; // 选中的来源通道名称
};
// 同一时刻聚合桶
// 含义:在“已筛选出的统计类 observation”内某个 timestamp 下所有已识别指标的统计值集合。
struct TimeAggregatedStatBucket
{
time_t timestamp = 0; // 聚合时刻
std::string timestamp_text; // 格式化时间文本
std::map<StatMetricId, AggregatedStatValues> metrics; // 当前时刻下各指标的统计值
};
// PQDIF 统计桶 Base64 子记录对象
// 对象用途:保存“一个 PQDIF 文件 + 一个时间点 + 一种统计类型”的最终 Base64 组装结果。
// 数据粒度:例如同一个时间点会有 Max、Min、Avg、P95 四条子记录。
// 注意v20 起它不再直接作为全局队列元素,而是作为
// PqdifStatBase64TimePointPacket.records 的子对象存在。
struct PqdifStatBase64Record
{
std::string pqdif_file_path; // 对象来源PQDIF 文件全路径,便于后续处理时追溯文件
StatValueKind value_kind = StatValueKind::Unknown; // 对象统计类型Max / Min / Avg / P95
std::string value_kind_name; // 对象统计类型文本:便于日志/外部队列直接查看
int value_kind_code = 0; // 对象统计类型编码兼容旧统计队列1=Max, 2=Min, 3=Avg, 4=P95
time_t timestamp = 0; // 对象时间戳:该 Base64 数据所属的桶时间点
std::string timestamp_text; // 对象时间文本:格式化时间点,便于日志、人眼核查
std::string base64_payload; // 对象数据主体float 按星型/角型顺序组装后整体转换成的 Base64 字符串
size_t float_count = 0; // 对象校验字段:本条记录实际组装的 float 数量
size_t placeholder_count = 0; // 对象校验字段:本条记录中使用 3.14159f 占位的数量
ParsedConnectionKind connection_kind = ParsedConnectionKind::Unknown; // 对象接线方式:星型/角型/未知
};
// PQDIF Base64 时间点包对象
// 对象用途:把同一个 PQDIF 文件、同一个时间点下的 Max/Min/Avg/P95 四类 Base64 子记录合并保存。
// 设计原因:后续处理时可以按时间点一次性拿到四种统计类型,避免散落成单条记录。
struct PqdifStatBase64TimePointPacket
{
time_t timestamp = 0; // 对象时间戳:该时间点包对应的桶时间点
std::string timestamp_text; // 对象时间文本:格式化时间点,便于日志、人眼核查
std::vector<PqdifStatBase64Record> records; // 对象子记录:同一时间点下的 Max/Min/Avg/P95 Base64 记录
size_t record_count = 0; // 对象统计字段records.size() 的冗余统计,便于日志核查
size_t total_float_count = 0; // 对象统计字段:当前时间点下所有子记录的 float 数量合计
size_t total_placeholder_count = 0;// 对象统计字段:当前时间点下所有子记录的占位数量合计
size_t total_base64_chars = 0; // 对象统计字段:当前时间点下所有子记录 base64 字符数合计
};
// PQDIF Base64 文件级批次对象
// 对象用途:保存“一个 PQDIF 文件解析完成后”的全部 Base64 时间点包。
// 数据粒度:全局队列中的一个元素就是一个 PqdifStatBase64FileBatch文件之间不会混合。
struct PqdifStatBase64FileBatch
{
std::string pqdif_file_path; // 对象来源PQDIF 文件全路径
std::string source_file; // 对象来源:原始文件路径,通常与 pqdif_file_path 一致或接近
std::string mac; // 对象来源:设备目录名/设备标识
time_t parsed_at = 0; // 对象生成时间戳:解析完成时间
std::string parsed_at_text; // 对象生成时间文本:格式化解析完成时间
ParsedConnectionKind connection_kind = ParsedConnectionKind::Unknown; // 对象接线方式:星型/角型/未知
std::vector<PqdifStatBase64TimePointPacket> time_points; // 对象主体:文件内所有时间点包
size_t time_point_count = 0; // 对象统计字段time_points.size() 的冗余统计,便于日志核查
size_t total_record_count = 0; // 对象统计字段:文件内全部 Max/Min/Avg/P95 子记录数量
size_t total_float_count = 0; // 对象统计字段:文件内全部 float 数量
size_t total_placeholder_count = 0;// 对象统计字段:文件内全部占位数量
size_t total_base64_chars = 0; // 对象统计字段:文件内全部 base64 字符数
};
// 一个 PQDIF 文件的暂存对象
struct ParsedPqdifFile
{
std::string mac; // 设备目录名
std::string source_file; // 原始文件路径
time_t parsed_at = 0; // 解析完成时间
// 新结构:完整 PQDIF 拆分结果
PqdifLogicalFile logical_file;
// 统计识别与聚合层结果
ParsedConnectionKind connection_kind = ParsedConnectionKind::Unknown; ///< 当前文件识别出的接线方式
int selected_observation_index = -1; ///< 当前阶段被选中的“统计类 observation”索引
std::string selected_observation_name; ///< 当前阶段被选中的“统计类 observation”名称
std::vector<ExpandedStatPoint> expanded_stat_points; ///< 从 PQDIF 展开的全部统计样本点
std::vector<TimeAggregatedStatBucket> aggregated_stat_buckets; ///< 按 timestamp 聚合后的时间桶
};
// 启动 PQDIF 扫描线程
void RunPqdifScanLoop();
// 缓存访问接口
bool PopOldestParsedPqdifFile(ParsedPqdifFile& out);
bool PeekOldestParsedPqdifFile(ParsedPqdifFile& out);
size_t GetParsedPqdifCacheSize();
void ClearParsedPqdifCache();
// PQDIF 统计桶 Base64 “生成队列”访问接口
// 对象用途该队列由解析流程写入RunPqdifScanLoop() 每轮循环末尾会尝试把其中一个文件批次
// 移动到“待后续处理队列”。如果外部仍需直接读取生成队列,可以继续使用以下旧接口。
// v20 起:队列元素 = 一个 PQDIF 文件批次。
bool PopOldestPqdifStatBase64FileBatch(PqdifStatBase64FileBatch& out);
bool PeekOldestPqdifStatBase64FileBatch(PqdifStatBase64FileBatch& out);
// 兼容旧接口:如旧代码仍按单条 Base64 子记录读取,会从文件批次队列的最早文件/最早时间点中拆出一条。
bool PopOldestPqdifStatBase64Record(PqdifStatBase64Record& out);
bool PeekOldestPqdifStatBase64Record(PqdifStatBase64Record& out);
// 返回当前生成队列文件级批次数量;如需查看内部子记录数量,使用 GetPqdifStatBase64RecordCountInQueue()。
size_t GetPqdifStatBase64QueueSize();
size_t GetPqdifStatBase64RecordCountInQueue();
void ClearPqdifStatBase64Queue();
// PQDIF 统计桶 Base64 “待后续处理队列”访问接口
// 对象用途RunPqdifScanLoop() 已经从生成队列取出、准备交给后续入库/上传/推送流程的数据会放在这里。
// 推荐后续业务优先调用 PopReadyPqdifStatBase64FileBatch(),一次取出一个完整 PQDIF 文件批次。
bool PopReadyPqdifStatBase64FileBatch(PqdifStatBase64FileBatch& out);
bool PeekReadyPqdifStatBase64FileBatch(PqdifStatBase64FileBatch& out);
size_t GetReadyPqdifStatBase64QueueSize();
size_t GetReadyPqdifStatBase64RecordCountInQueue();
void ClearReadyPqdifStatBase64Queue();