Compare commits

72 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
d460816195 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2026-02-28 09:22:54 +08:00
9559f288ca 添加手动对时类型 2026-02-28 09:22:47 +08:00
lnk
7312bc68d7 add log level control by ledger 2026-02-06 15:27:52 +08:00
lnk
2b4c939b79 use ledger log level 2026-02-04 17:03:14 +08:00
lnk
787d1f20be modify log 2026-01-30 16:28:47 +08:00
lnk
6f0ee17da2 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2026-01-23 16:11:13 +08:00
lnk
529abd4d55 modify log 2026-01-23 16:10:51 +08:00
a4cd9cf62f 调整了实时数据电压偏差和负序不平衡的上送 2026-01-15 13:49:58 +08:00
1c76a9a1ce 调整了电压偏差上送方式,取上下偏差中绝对值较大的那一个指标 2026-01-14 20:22:29 +08:00
3e05e627d3 实时数据添加了基波指标 2026-01-14 13:34:37 +08:00
c97b83d83d 调整了装置上送统计数据的逻辑,现在只上送二次值, 2026-01-13 16:27:50 +08:00
lnk
a87504cee9 add test fun 2026-01-09 16:33:08 +08:00
lnk
709fdfc284 fix rtdata log error 2026-01-09 14:59:35 +08:00
lnk
c538161074 fix devname bug 2026-01-08 16:51:08 +08:00
lnk
d18eb0d157 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2026-01-08 15:56:21 +08:00
lnk
df9760c1a7 add function,1.limit log freq 2.realtime log control 2026-01-08 15:55:46 +08:00
7c676162ef Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2026-01-07 11:15:26 +08:00
cab2ab3453 添加了两个普通日志 2026-01-07 11:15:22 +08:00
lnk
02127869c0 add fun in log4 2026-01-07 11:02:03 +08:00
lnk
be068fab40 fix log 2026-01-06 16:25:08 +08:00
lnk
a71735b983 modify log format 2026-01-06 15:42:31 +08:00
lnk
7725fd2d87 fix comtrade file pair 2026-01-05 16:29:42 +08:00
lnk
dd01a31a77 fix coredump error 2025-12-23 15:09:28 +08:00
lnk
1014aeafbc add comment 2025-12-22 11:42:02 +08:00
lnk
c5ded4c032 fix recall file 2025-12-18 11:42:57 +08:00
lnk
44852a0846 fix mq log control 2025-12-15 10:55:58 +08:00
lnk
50f82af3f3 add mq log control 2025-12-15 10:29:46 +08:00
lnk
2c48d7ae0a fix data race 2025-12-11 15:07:54 +08:00
lnk
7dbd4593fa remove useless code 2025-12-11 09:26:08 +08:00
lnk
e615188bb1 fix memleak 2025-12-09 16:29:55 +08:00
lnk
b4ce0fa5f9 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2025-12-08 15:34:53 +08:00
lnk
56382e9ccd modify threads 2025-12-08 15:34:46 +08:00
0c239be9a7 正负零分量调整 2025-12-08 15:21:15 +08:00
b08c632de4 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2025-12-02 10:53:52 +08:00
a1d8a55357 统计数据转换结构调整 2025-12-02 10:52:06 +08:00
lnk
93143fcba6 modify recall 2025-11-05 15:24:59 +08:00
lnk
02d2b021cd fix recall 2025-11-04 15:42:40 +08:00
lnk
beedb9aeca modify timeout 2025-11-04 10:00:29 +08:00
lnk
ba142d3fd3 fix single recall wave 2025-11-03 15:39:29 +08:00
lnk
c02f0cbbdd fix recall 2025-10-31 10:59:30 +08:00
lnk
5e63adc8f9 fix recall 2025-10-30 20:57:19 +08:00
lnk
06a2f3a75b fix wave 2025-10-28 20:59:05 +08:00
lnk
f69a6d2105 fix recall 2025-10-24 17:07:51 +08:00
lnk
07ac84d612 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2025-10-24 08:51:01 +08:00
lnk
fdd6a30fe2 modify recall 2025-10-24 08:50:54 +08:00
5ebb179c44 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2025-10-24 08:46:29 +08:00
fdbefa50ac 取消了测试告警的代码 2025-10-24 08:46:24 +08:00
lnk
a755c6faab recall modify 2025-10-22 15:57:50 +08:00
c7e7cd9078 Merge branch '测试2' of http://192.168.1.22:3000/zhangwen/front_linux into 测试2 2025-10-16 15:04:28 +08:00
ff67e5320f 调整了设备移除函数,现在不会异常崩溃了 2025-10-16 15:04:22 +08:00
lnk
c55f2ab1af modify recall 2025-10-15 16:29:54 +08:00
100 changed files with 41633 additions and 1234 deletions

View File

@@ -127,7 +127,8 @@
"cinttypes": "cpp",
"typeinfo": "cpp",
"valarray": "cpp",
"variant": "cpp"
"variant": "cpp",
"unordered_set": "cpp"
},
"cmake.sourceDirectory": "D:/canneng/云前置移植项目/zw/Linux_Front1056/LFtid1056/lib/libuv-v1.51.0"
}

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ֵ)
@@ -765,4 +982,34 @@ 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>
@@ -599,10 +621,10 @@ public:
for (int j = 0; j < 4; j++) {
if (i == 0) { // <20><>ѹ
if (j == 2) { // <20><><EFBFBD><EFBFBD>
UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]) * fPT;
UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]);// *fPT;
}
else if (j < 3) {
UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]) * fPT * 1000.0f;
UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]);// *fPT;
}
else {
UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]);
@@ -610,7 +632,7 @@ public:
}
else { // <20><><EFBFBD><EFBFBD>
if (j < 3) {
UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]) * fCT;
UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]);// *fCT;
}
else {
UI_Seq[i][j] = IntToFloat(SrcData.UI_Seq[i][j]);
@@ -635,16 +657,16 @@ public:
// <20>ܹ<EFBFBD><DCB9><EFBFBD>
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 3; j++) {
Total_Power[i][j] = IntToFloat(SrcData.Total_Power[i][j]) * fPT * fCT;
Total_Power[i][j] = IntToFloat(SrcData.Total_Power[i][j]);// *fPT* fCT;
}
}
// г<><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int i = 0; i < 4; i++) {
for (int j = 0; j < HARMNUM; j++) {
Harm_Power[i][j].P = IntToFloat(SrcData.Harm_Power[i][j].P) * fPT * fCT;
Harm_Power[i][j].Q = IntToFloat(SrcData.Harm_Power[i][j].Q) * fPT * fCT;
Harm_Power[i][j].S = IntToFloat(SrcData.Harm_Power[i][j].S) * fPT * fCT;
Harm_Power[i][j].P = IntToFloat(SrcData.Harm_Power[i][j].P);// * fPT * fCT;
Harm_Power[i][j].Q = IntToFloat(SrcData.Harm_Power[i][j].Q);// *fPT* fCT;
Harm_Power[i][j].S = IntToFloat(SrcData.Harm_Power[i][j].S);// *fPT* fCT;
}
}
@@ -656,10 +678,10 @@ public:
for (int j = 0; j < HARMNUM; j++) {
if (i < 3) { // <20><>ѹг<D1B9><D0B3>
FuHarm[i][j] = IntToFloat(SrcData.FuHarm[i][j]) * fPT;
FuHarm[i][j] = IntToFloat(SrcData.FuHarm[i][j]);// *fPT;
}
else { // <20><><EFBFBD><EFBFBD>г<EFBFBD><D0B3>
FuHarm[i][j] = IntToFloat(SrcData.FuHarm[i][j]) * fCT;
FuHarm[i][j] = IntToFloat(SrcData.FuHarm[i][j]);// *fCT;
}
FuHarmPhase[i][j] = IntToFloat(SrcData.FuHarmPhase[i][j]);
@@ -671,10 +693,10 @@ public:
// RMSֵ
for (int i = 0; i < 9; i++) {
if (i > 2 && i < 6) { // <20><><EFBFBD><EFBFBD> (<28><><EFBFBD><EFBFBD>3,4,5)
Rms[i] = IntToFloat(SrcData.Rms[i]) * fCT;
Rms[i] = IntToFloat(SrcData.Rms[i]);// *fCT;
}
else { // <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Rms[i] = IntToFloat(SrcData.Rms[i]) * fPT;
Rms[i] = IntToFloat(SrcData.Rms[i]);// *fPT;
}
}
}
@@ -757,7 +779,10 @@ public:
// 12-14λ<34><CEBB>UU_Deviation<6F><6E>UL_Deviation<6F><6E><EFBFBD><EFBFBD>ȡǰ<C8A1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>Ϊ0<CEAA><30>ֵ
for (int i = 0; i < 3; ++i) {
float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i];
// ֱ<><D6B1>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ֵ<EFBFBD><D6B5>
float val = (fabs(UU_Deviation[i]) > fabs(UL_Deviation[i]))
? UU_Deviation[i]
: -UL_Deviation[i];
float_buffer.push_back(val);
}
@@ -981,6 +1006,40 @@ public:
float_buffer.push_back(UL_Flicker[i]);
}
//<2F><>12λ A<><41>P1 Q1 S1 B<><42>P1 Q1 S1 C<><43>P1 Q1 S1 T<><54>P1 Q1 S1
float_buffer.push_back(Harm_Power[0][0].P);
float_buffer.push_back(Harm_Power[0][0].Q);
float_buffer.push_back(Harm_Power[0][0].S);
float_buffer.push_back(Harm_Power[1][0].P);
float_buffer.push_back(Harm_Power[1][0].Q);
float_buffer.push_back(Harm_Power[1][0].S);
float_buffer.push_back(Harm_Power[2][0].P);
float_buffer.push_back(Harm_Power[2][0].Q);
float_buffer.push_back(Harm_Power[2][0].S);
float_buffer.push_back(Harm_Power[3][0].P);
float_buffer.push_back(Harm_Power[3][0].Q);
float_buffer.push_back(Harm_Power[3][0].S);
//<2F><><20><><EFBFBD><EFBFBD>ѹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ߵ<EFBFBD>ѹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Чֵ A B C V1 I1<49><31>FuHarmȡ<6D><C8A1><EFBFBD><EFBFBD>
float_buffer.push_back(3.14159f);//A V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//B V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//C V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(FuHarm[3][0]);//A I1
float_buffer.push_back(FuHarm[4][0]);//B I1
float_buffer.push_back(FuHarm[5][0]);//C I1
float_buffer.push_back(FuHarm[0][0]);//AB V1
float_buffer.push_back(FuHarm[1][0]);//BC V1
float_buffer.push_back(FuHarm[2][0]);//CA V1
//<2F><><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FuHarmPhaseȡ<65><C8A1><EFBFBD><EFBFBD>
float_buffer.push_back(3.14159f);//A V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//B V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//C V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(FuHarmPhase[3][0]);//A I1
float_buffer.push_back(FuHarmPhase[4][0]);//B I1
float_buffer.push_back(FuHarmPhase[5][0]);//C I1
float_buffer.push_back(FuHarmPhase[0][0]);//AB V1
float_buffer.push_back(FuHarmPhase[1][0]);//BC V1
float_buffer.push_back(FuHarmPhase[2][0]);//CA V1
// ת<><D7AA>ΪBase64
const size_t byte_size = float_buffer.size() * sizeof(float);
const unsigned char* byte_data = reinterpret_cast<const unsigned char*>(float_buffer.data());
@@ -998,7 +1057,10 @@ public:
// 9-11λ<31><CEBB>UU_Deviation<6F><6E>UL_Deviation<6F><6E><EFBFBD><EFBFBD>ȡǰ<C8A1><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><C8A1>Ϊ0<CEAA><30>ֵ
for (int i = 0; i < 3; ++i) {
float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i];
// ֱ<><D6B1>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ֵ<EFBFBD><D6B5>
float val = (fabs(UU_Deviation[i]) > fabs(UL_Deviation[i]))
? UU_Deviation[i]
: -UL_Deviation[i];
float_buffer.push_back(val);
}
@@ -1190,6 +1252,40 @@ public:
float_buffer.push_back(3.14159f);
}
//<2F><>12λ A<><41>P1 Q1 S1 B<><42>P1 Q1 S1 C<><43>P1 Q1 S1 T<><54>P1 Q1 S1
float_buffer.push_back(Harm_Power[0][0].P);
float_buffer.push_back(Harm_Power[0][0].Q);
float_buffer.push_back(Harm_Power[0][0].S);
float_buffer.push_back(Harm_Power[1][0].P);
float_buffer.push_back(Harm_Power[1][0].Q);
float_buffer.push_back(Harm_Power[1][0].S);
float_buffer.push_back(Harm_Power[2][0].P);
float_buffer.push_back(Harm_Power[2][0].Q);
float_buffer.push_back(Harm_Power[2][0].S);
float_buffer.push_back(Harm_Power[3][0].P);
float_buffer.push_back(Harm_Power[3][0].Q);
float_buffer.push_back(Harm_Power[3][0].S);
//<2F><><20><><EFBFBD><EFBFBD>ѹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ߵ<EFBFBD>ѹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Чֵ A B C V1 I1<49><31>FuHarmȡ<6D><C8A1><EFBFBD><EFBFBD>
float_buffer.push_back(FuHarm[0][0]);//A V1
float_buffer.push_back(FuHarm[1][0]);//B V1
float_buffer.push_back(FuHarm[2][0]);//C V1
float_buffer.push_back(FuHarm[3][0]);//A I1
float_buffer.push_back(FuHarm[4][0]);//B I1
float_buffer.push_back(FuHarm[5][0]);//C I1
float_buffer.push_back(3.14159f);//AB V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//BC V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//CA V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
//<2F><><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FuHarmPhaseȡ<65><C8A1><EFBFBD><EFBFBD>
float_buffer.push_back(FuHarmPhase[0][0]);//A V1
float_buffer.push_back(FuHarmPhase[1][0]);//B V1
float_buffer.push_back(FuHarmPhase[2][0]);//C V1
float_buffer.push_back(FuHarmPhase[3][0]);//A I1
float_buffer.push_back(FuHarmPhase[4][0]);//B I1
float_buffer.push_back(FuHarmPhase[5][0]);//C I1
float_buffer.push_back(3.14159f);//AB V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//BC V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//CA V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
// ת<><D7AA>ΪBase64
const size_t byte_size = float_buffer.size() * sizeof(float);
const unsigned char* byte_data = reinterpret_cast<const unsigned char*>(float_buffer.data());
@@ -1741,7 +1837,11 @@ public:
// 9-11: <20><>ѹƫ<D1B9>ȡ<EEA3A8><C8A1>Ϊ0<CEAA><30>ֵ<EFBFBD><D6B5>
for (int i = 0; i < 3; ++i) {
float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i];
//float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i];
// ֱ<><D6B1>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ֵ<EFBFBD><D6B5>
float val = (fabs(UU_Deviation[i]) > fabs(UL_Deviation[i]))
? UU_Deviation[i]
: -UL_Deviation[i];
float_buffer.push_back(val);
}
@@ -1768,7 +1868,12 @@ public:
// 26-33: <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ8<C7B0><38>Ԫ<EFBFBD>أ<EFBFBD>
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 4; ++j) { // ȡÿ<C8A1>е<EFBFBD>ǰ4<C7B0><34>Ԫ<EFBFBD><D4AA>
float_buffer.push_back(UI_Seq[i][j]);
if (j == 3) {
float_buffer.push_back(UI_Seq[i][j+1]);
}
else {
float_buffer.push_back(UI_Seq[i][j]);
}
}
}
@@ -1839,6 +1944,27 @@ public:
float_buffer.push_back(3.14159f);
}
//<2F><><20><><EFBFBD><EFBFBD>ѹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ߵ<EFBFBD>ѹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Чֵ A B C V1 I1<49><31>FuHarmȡ<6D><C8A1><EFBFBD><EFBFBD>
float_buffer.push_back(HARMV[0][0]);//A V1
float_buffer.push_back(HARMV[1][0]);//B V1
float_buffer.push_back(HARMV[2][0]);//C V1
float_buffer.push_back(HARMI[0][0]);//A I1
float_buffer.push_back(HARMI[1][0]);//B I1
float_buffer.push_back(HARMI[2][0]);//C I1
float_buffer.push_back(3.14159f);//AB V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//BC V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//CA V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
//<2F><><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FuHarmPhaseȡ<65><C8A1><EFBFBD><EFBFBD>
float_buffer.push_back(HARMVP[0][0]);//A V1
float_buffer.push_back(HARMVP[1][0]);//B V1
float_buffer.push_back(HARMVP[2][0]);//C V1
float_buffer.push_back(HARMIP[0][0]);//A I1
float_buffer.push_back(HARMIP[1][0]);//B I1
float_buffer.push_back(HARMIP[2][0]);//C I1
float_buffer.push_back(3.14159f);//AB V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//BC V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//CA V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
// ת<><D7AA>ΪBase64
return floatVectorToBase64(float_buffer);
}
@@ -1859,7 +1985,11 @@ public:
// 12-14: <20><>ѹƫ<D1B9>ȡ<EEA3A8><C8A1>Ϊ0<CEAA><30>ֵ<EFBFBD><D6B5>
for (int i = 0; i < 3; ++i) {
float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i];
//float val = (UU_Deviation[i] != 0.0f) ? UU_Deviation[i] : UL_Deviation[i];
// ֱ<><D6B1>ѡ<EFBFBD><D1A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ǹ<EFBFBD><C7B8><EFBFBD><EFBFBD><EFBFBD>Ȼ<EFBFBD><C8BB><EFBFBD><EFBFBD>Ч<EFBFBD><D0A7>ֵ<EFBFBD><D6B5>
float val = (fabs(UU_Deviation[i]) > fabs(UL_Deviation[i]))
? UU_Deviation[i]
: -UL_Deviation[i];
float_buffer.push_back(val);
}
@@ -1886,7 +2016,12 @@ public:
// 26-33: <20><>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǰ8<C7B0><38>Ԫ<EFBFBD>أ<EFBFBD>
for (int i = 0; i < 2; ++i) {
for (int j = 0; j < 4; ++j) {
float_buffer.push_back(UI_Seq[i][j]);
if (j == 3) {
float_buffer.push_back(UI_Seq[i][j + 1]);
}
else {
float_buffer.push_back(UI_Seq[i][j]);
}
}
}
@@ -1957,6 +2092,27 @@ public:
}
}
//<2F><><20><><EFBFBD><EFBFBD>ѹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20>ߵ<EFBFBD>ѹ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Чֵ A B C V1 I1<49><31>FuHarmȡ<6D><C8A1><EFBFBD><EFBFBD>
float_buffer.push_back(3.14159f);//A V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//B V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//C V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(HARMI[0][0]);//A I1
float_buffer.push_back(HARMI[1][0]);//B I1
float_buffer.push_back(HARMI[2][0]);//C I1
float_buffer.push_back(HARMV[0][0]);//AB V1
float_buffer.push_back(HARMV[1][0]);//BC V1
float_buffer.push_back(HARMV[2][0]);//CA V1
//<2F><><20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> FuHarmPhaseȡ<65><C8A1><EFBFBD><EFBFBD>
float_buffer.push_back(3.14159f);//A V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//B V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(3.14159f);//C V1 <20><><EFBFBD>Ϳ<EFBFBD><CDBF><EFBFBD>
float_buffer.push_back(HARMIP[0][0]);//A I1
float_buffer.push_back(HARMIP[1][0]);//B I1
float_buffer.push_back(HARMIP[2][0]);//C I1
float_buffer.push_back(HARMVP[0][0]);//AB V1
float_buffer.push_back(HARMVP[1][0]);//BC V1
float_buffer.push_back(HARMVP[2][0]);//CA V1
// ת<><D7AA>ΪBase64
return floatVectorToBase64(float_buffer);
}
@@ -1966,7 +2122,11 @@ public:
std::vector<float> float_buffer;
//THD<48>ߵ<EFBFBD>ѹ<EFBFBD><D1B9><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>3-5<><35>
for (int i = 3; i < 6; ++i) {
/*for (int i = 3; i < 6; ++i) {
float_buffer.push_back(THD[i]);
}*/
//<2F><><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ָ<EFBFBD><EFBFBD><EAB1BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ȼȡ0-2<><32><EFBFBD><EFBFBD>ȡ3-5
for (int i = 0; i < 3; ++i) {
float_buffer.push_back(THD[i]);
}
@@ -1985,7 +2145,7 @@ public:
std::string ConvertToBase64_Star_RtHarmV() const {
std::vector<float> float_buffer;
//THD<48>ߵ<EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>3-5<EFBFBD><EFBFBD>
//THD<48><EFBFBD><EFBFBD><EFBFBD>ѹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʣ<EFBFBD>0-2<EFBFBD><EFBFBD>
for (int i = 0; i < 3; ++i) {
float_buffer.push_back(THD[i]);
}
@@ -2231,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>
@@ -2265,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ֵ)
@@ -2279,4 +2497,16 @@ std::vector<uint8_t> generate_righttime_message(const std::tm& time);
* @param monitorPoint <20><><EFBFBD><EFBFBD><EFBFBD>㣬Ĭ<E3A3AC><C4AC>1-<2D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1 1-6 <20><>Ӧ<EFBFBD><D3A6><EFBFBD><EFBFBD>
* @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);
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 库就加上
@@ -49,11 +59,11 @@ fi
# 判断是否为 debug 版本
if [[ "$1" == "debug" ]]; then
CXXFLAGS="-std=c++11 -g -O0"
CXXFLAGS="-std=c++11 -g -O0 -Wformat -Wformat-security -Werror=format"
TARGET="${TARGET}d"
echo "🟢 编译调试版本 (-g -O0)"
else
CXXFLAGS="-std=c++11 -O2 -static-libstdc++ -static-libgcc"
CXXFLAGS="-std=c++11 -O2 -static-libstdc++ -static-libgcc -Wformat -Wformat-security -Werror=format"
echo "🔵 编译正式版本 (-O2 -static)"
fi
@@ -67,4 +77,4 @@ if [ $? -eq 0 ]; then
ldd "$OUT_DIR/$TARGET" || echo "是静态编译程序 ✔"
else
echo "❌ 编译失败"
fi
fi

File diff suppressed because it is too large Load Diff

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>
@@ -60,9 +66,13 @@ enum class DeviceState {
READING_RUNNINGINFORMATION_1,// <20><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
READING_RUNNINGINFORMATION_2,// <20><>ȡװ<C8A1><D7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ(<28><>ʱִ<CAB1><D6B4>)
READING_DEVVERSION, // <20><>ȡװ<C8A1>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
SET_RIGHTTIME, // <20><><EFBFBD><EFBFBD>װ<EFBFBD>ö<EFBFBD>ʱ
SET_RIGHTTIME, // <20><><EFBFBD><EFBFBD>װ<EFBFBD>ö<EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱִ<EFBFBD>У<EFBFBD>
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>
};
@@ -82,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>ȫ
@@ -140,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 {
@@ -200,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>
@@ -246,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_;
@@ -402,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);
@@ -418,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);
@@ -442,6 +574,64 @@ public:
//<2F><>ȡװ<C8A1>ð汾<C3B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϣ
bool read_devversion_action_to_device(const std::string& identifier);
//װ<><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);
/**
@@ -453,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

@@ -94,6 +94,11 @@ public:
std::atomic<bool> m_bIsFrontThreadCancle{false};
std::atomic<bool> m_IsMQConsumerCancel{false};
std::atomic<bool> m_frontRunning{false};
std::atomic<bool> m_consumerRunning{false};
std::atomic<bool> m_producerRunning{false};
std::atomic<bool> m_timerRunning{false};
std::mutex m_threadCheckMutex;
std::atomic<bool> m_needRestartFrontThread{false};
std::atomic<bool> m_needRestartConsumerThread{false};
@@ -110,6 +115,12 @@ public:
void StartMQProducerThread();
void StartTimerThread();
// [ADD] 统一的停止接口(便于重启前先停干净)
void StopFrontThread();
void StopMQConsumerThread();
void StopMQProducerThread();
void StopTimerThread();
void FrontThread();
void mqconsumerThread();
void mqproducerThread();

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 这个名字带到当前作用域
@@ -147,14 +222,14 @@ void handleUploadResponse(const std::string& response, std::string& wavepath) {
}
catch (const json::parse_error& e) {
std::cerr << "Error parsing response: " << e.what() << std::endl;
DIY_ERRORLOG("process", "【ERROR】前置上传暂态录波文件失败,web返回的消息不是json格式");
DIY_ERRORLOG_CODE("process",0,LOG_CODE_JSON, "文件上传接口响应异常,上传文件失败");
return;
}
// 提取字段
if (!json_data.contains("code") || !json_data.contains("data")) {
std::cerr << "Error: Missing expected fields in JSON response." << std::endl;
DIY_ERRORLOG("process", "【ERROR】前置上传暂态录波文件失败,web返回的消息没有远端文件名");
DIY_ERRORLOG_CODE("process",0,LOG_CODE_JSON, "文件上传接口响应异常,上传文件失败");
return;
}
@@ -167,7 +242,7 @@ void handleUploadResponse(const std::string& response, std::string& wavepath) {
auto& data = json_data["data"];
if (!data.contains("name") || !data.contains("fileName") || !data.contains("url")) {
std::cerr << "Error: Missing expected fields in JSON data object." << std::endl;
DIY_ERRORLOG("process", "【ERROR】前置上传暂态录波文件失败,web返回的消息没有远端文件名");
DIY_ERRORLOG_CODE("process",0,LOG_CODE_JSON, "文件上传接口响应异常,上传文件失败");
return;
}
@@ -183,23 +258,32 @@ 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;
std::cout << "wavepath: " << wavepath << std::endl;
DIY_INFOLOG("process", "【NORMAL】前置上传暂态录波文件成功,远端文件名:%s", wavepath.c_str());
DIY_INFOLOG_CODE("process",0,LOG_CODE_FILE, "上传文件成功,远端文件名:%s", wavepath.c_str());
}
//上传文件
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) {
@@ -271,10 +355,10 @@ void SendFileWeb(const std::string& strUrl, const std::string& localpath, const
if (res != CURLE_OK) {
const char* em = errbuf[0] ? errbuf : curl_easy_strerror(res);
std::cerr << "http web failed: " << em << std::endl;
DIY_ERRORLOG("process","【ERROR】前置上传暂态录波文件 %s 失败,请检查文件上传接口配置",localpath);
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,
@@ -389,7 +582,7 @@ void download_xml_for_icd(const std::string& MODEL_ID,
std::cout << "remote file name:" << remote_file_name << "local save name:" << save_name << std::endl;
// mq日志
DIY_WARNLOG("process","【WARN】前置获取到终端类型%s,该终端类型对应的映射文件为%s,映射文件将下载并保存在本地为%s",TMNL_TYPE,FILE_PATH,save_name);
std::string fileContent;
std::string fullPath = std::string("filePath=") + filepath; //填写远端路径作为入参
@@ -409,14 +602,14 @@ void download_xml_for_icd(const std::string& MODEL_ID,
outFile.close();
std::cout << "File saved successfully!" << std::endl;
DIY_WARNLOG("process","【WARN】前置下载映射文件%s成功",save_name);
} else {
std::cerr << "Error: Unable to open file for writing." << std::endl;
DIY_ERRORLOG("process","【ERROR】前置写入本地映射文件%s失败",save_name);
}
} else {
std::cerr << "Error: Unable to download file." << std::endl;
DIY_ERRORLOG("process","【ERROR】前置调用文件下载接口下载远端文件文件%s失败",FILE_PATH);
}
}
@@ -550,7 +743,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
{
if (inputstring.empty()) {
std::cerr << "Error: inputstring is empty\n";
DIY_ERRORLOG("process","【ERROR】前置的%d号进程调用web台账接口的入参为空", g_front_seg_index);
DIY_ERRORLOG_CODE("process",0,LOG_CODE_CONFIG,"调用台账接口的入参为空,无法获取台账信息");
return 1;
}
@@ -569,7 +762,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
break;
}
std::cerr << "data 无效或为空数组,重试\n";
DIY_ERRORLOG("process","【ERROR】前置从web接口中获取的台账信息为空或者无效信息无法解析,请核对前置使用的入参信息:%s",inputparm.c_str());
DIY_ERRORLOG_CODE("process",0,LOG_CODE_JSON,"从台账接口中获取的台账信息为无效信息,台账初始化失败");
} catch (const nlohmann::json::parse_error& e) {
std::cerr << "parse error: " << e.what() << ", retrying...\n";
}
@@ -579,6 +772,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
if (++retry > 3) {
std::cerr << "web error after 3 retry, fallback to local file\n";
DIY_WARNLOG_CODE("process",0,LOG_CODE_CONFIG, "无法从台账接口获取台账,将从本地读取上一次缓存的台账");
std::string ledger = read_latest_ledger_file();
if (!ledger.empty()) {
try {
@@ -586,7 +780,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
if (json_data.contains("data") && json_data["data"].is_array() && !json_data["data"].empty()) {
break;
}
DIY_ERRORLOG("process", "【ERROR】前置从本地台账中获取的台账信息为空或者无效信息无法解析,请核对前置使用的入参信息:%s",inputparm.c_str());
DIY_ERRORLOG_CODE("process",0,LOG_CODE_JSON,"从本地台账中获取的台账信息为无效信息,台账初始化失败");
} catch (const nlohmann::json::parse_error& e) {
std::cerr << "local parse error: " << e.what() << "\n";
}
@@ -600,7 +794,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
// 2. 安全读取 code/msg
std::string code = json_data.value("code", "not found");
std::string msg = json_data.value("msg", "not found");
std::string msg = json_data.value("message", "not found");
std::cout << "code: " << code << "\n";
std::cout << "msg : " << msg << "\n";
@@ -630,16 +824,17 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
//dev.station_name = safe_str(item, "stationName");
//dev.tmnl_factory = safe_str(item, "manufacturer");
//dev.tmnl_status = safe_str(item, "status");
dev.dev_type = safe_str(item, "devType");
dev.dev_type = safe_str(item, "devType");
dev.DevLogLevel = safe_str(item, "devLogLevel");
//dev.dev_key = safe_str(item, "devKey");
//dev.dev_series = safe_str(item, "series");
//dev.port = safe_str(item, "port");
//dev.timestamp = safe_str(item, "updateTime");
dev.Righttime = safe_str(item, "Righttime");
dev.Righttime = safe_str(item, "rightTime");
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"]) {
@@ -651,6 +846,7 @@ int terminal_ledger_web(std::map<std::string, terminal_dev>& terminal_dev_map,
m.logical_device_seq = safe_str(mon, "lineNo");
m.voltage_level = safe_str(mon, "voltageLevel");
m.terminal_connect = safe_str(mon, "ptType");
m.LineLogLevel = safe_str(mon, "lineLogLevel");
//m.timestamp = safe_str(mon, "updateTime");
m.status = safe_str(mon, "status");
@@ -709,7 +905,7 @@ int parse_device_cfg_web()
input_jstr += "}";
std::cout << "input_jstr: " << input_jstr << std::endl;
DIY_DEBUGLOG("process","【DEBUG】前置的%d号进程调用web接口获取台账使用的请求输入:%s", g_front_seg_index, input_jstr.c_str());
DIY_DEBUGLOG_CODE("process",0,LOG_CODE_LEDGER,"台账接口输入:%s", input_jstr.c_str());
// 2. 调用接口
std::map<std::string, terminal_dev> terminal_dev_map;
@@ -738,10 +934,10 @@ int parse_device_cfg_web()
if (max_process_num != max_index) {
if (max_process_num >= 1 && max_process_num <= 9) {
DIY_WARNLOG("process", "【WARN】前置比对台账获取的进程数:%d和本地配置的进程数:%d,不匹配,按照台账进程数重置前置的进程数量",max_process_num, max_index);
DIY_WARNLOG_CODE("process",0,LOG_CODE_CONFIG, "台账获取的进程数:%d和原有的进程数:%d不一致,将按照台账获取到的进程数重置进程",max_process_num, max_index);
execute_bash("reset", max_process_num, "all");
} else {
DIY_ERRORLOG("process","【ERROR】前置从台账获取进程数:%d不符合范围1~9,按照本地配置进程数启动进程",max_process_num);
DIY_ERRORLOG_CODE("process",0,LOG_CODE_CONFIG, "从台账获取到的总进程数:%d不符合范围1~9,不会重置进程",max_process_num);
}
}
}
@@ -749,13 +945,13 @@ int parse_device_cfg_web()
// 5. 台账数量与配置比对
int count_cfg = static_cast<int>(terminal_dev_map.size());
std::cout << "terminal_ledger_num: " << count_cfg << std::endl;
DIY_DEBUGLOG("process", "【DEBUG】前置的%d号进程调用获取到台账数量:%d", g_front_seg_index, count_cfg);
DIY_DEBUGLOG_CODE("process",0,LOG_CODE_LEDGER,"获取到台账数量:%d",count_cfg);
if (IED_COUNT < count_cfg) {
std::cout << "!!!!!!!!!!single process has ledger count more than config!!!!!!!" << std::endl;
//DIY_WARNLOG("process","【WARN】前置的%d号进程获取到的台账的数量大于配置文件中给单个进程配置的台账数量:%d,这个进程将按照获取到的台账的数量来创建台账空间,这个进程不能直接通过台账添加来新增台账,只能通过重启进程或者先删除已有台账再添加台账的方式来添加新台账", g_front_seg_index, IED_COUNT);
} else {
//DIY_INFOLOG("process","【NORMAL】前置的%d号进程根据配置文件中给单个进程配置的台账数量:%d来创建台账空间", g_front_seg_index, IED_COUNT);
}
///////////////////////////////////////////////////////////////////////////////用例这里将局部的map拷贝到全局map后续根据协议台账修改
@@ -801,13 +997,16 @@ int parse_device_cfg_web()
terminal_devlist.push_back(dev);
}
//记录所有logger等级
refresh_log_level_cache_locked();
// 判断监测点接线类型
for (auto& dev : terminal_devlist) {
for (auto& mon : dev.line) {
if (!mon.terminal_connect.empty() && mon.terminal_connect != "0") {
isdelta_flag = 1;
std::cout << "monitor_id " << mon.monitor_id<< " v_wiring_type: " << mon.terminal_connect << " is delta wiring: " << isdelta_flag << std::endl;
DIY_WARNLOG("process","【WARN】前置连接的监测点%s是角形接线,对应终端为%s 终端类型是%s",mon.monitor_id.c_str(),dev.terminal_id.c_str(),dev.dev_type.c_str());
//DIY_WARNLOG_CODE("process",0,LOG_CODE_WIRETYPE,"装置:%s - 监测点: %s 是角形接线",dev.terminal_name.c_str(),mon.monitor_name.c_str());
}
}
}
@@ -938,7 +1137,7 @@ int parse_model_cfg_web()
// 3. 调用接口
std::map<std::string, icd_model*> icd_model_map;
if (parse_model_web(&icd_model_map, input_jstr)) {
DIY_ERRORLOG("process", "【ERROR】前置的%d号进程 icd模型接口异常,将使用默认的icd模型,请检查接口配置", g_front_seg_index);
// 确保释放 map
for (auto& kv : icd_model_map) delete kv.second;
return 0;
@@ -992,7 +1191,7 @@ std::string parse_model_cfg_web_one(const std::string& terminal_type)
// 2. 拉取并解析
if (parse_model_web(&icd_model_map, input_jstr) != 0) {
std::cerr << "parse_model_web failed for type: " << terminal_type << std::endl;
DIY_ERRORLOG("process","【ERROR】前置的%d号进程 icd模型接口异常,将使用默认的icd模型,请检查接口配置", g_front_seg_index);
// 清理(即使 map 为空,也安全)
for (auto& kv : icd_model_map) delete kv.second;
return "";
@@ -1054,7 +1253,7 @@ static void writeJsonToFile(const std::string& filePath, const std::string& json
{
FILE* fp = fopen(filePath.c_str(), "w");
if (!fp) {
DIY_ERRORLOG("process", "【ERROR】无法将暂态事件写入本地缓存");
DIY_ERRORLOG_CODE("process",0,LOG_CODE_TRANSIENT_COMM, "无法将暂态事件写入本地缓存,暂态事件保存失败");
std::cerr << "Failed to write in file : " << filePath << std::endl;
return;
}
@@ -1166,7 +1365,7 @@ static void scanAndResendOfflineFiles(const std::string& dirPath)
// 读取 JSON 文件内容
std::ifstream inFile(file.fileName.c_str());
if (!inFile) {
DIY_ERRORLOG("process", "【ERROR】无法打开本地缓存的暂态事件");
DIY_ERRORLOG_CODE("process",0,LOG_CODE_TRANSIENT_COMM, "无法打开本地缓存的暂态事件,暂态事件重发失败");
std::cerr << "fail to open existing file: " << file.fileName << std::endl;
continue;
}
@@ -1185,14 +1384,14 @@ static void scanAndResendOfflineFiles(const std::string& dirPath)
try {
json j_r = json::parse(response);
DIY_WARNLOG("process", "【WARN】前置重发暂态事件成功");
DIY_WARNLOG_CODE("process",0,LOG_CODE_TRANSIENT_COMM, "重发暂态事件成功");
std::cout << "old file send success, remove it" << std::endl;
std::remove(file.fileName.c_str());
} catch (...) {
std::cout << "old file send fail (response parse failed)" << std::endl;
DIY_WARNLOG("process", "【WARN】前置重发暂态事件失败");
DIY_ERRORLOG_CODE("process",0,LOG_CODE_TRANSIENT_COMM, "暂态接口响应异常,重发暂态事件失败");
handleCommentResponse(response); // 仍然处理文本响应
}
} else {
@@ -1230,12 +1429,24 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
//找监测点id
std::string mpid;
//找测点名称
std::string mpname;
//找装置名称
std::string devname;
get_monitor_id_by_dev_and_seq(dev_id, monitor_id, mpid);
if(mpid.empty()) {
std::cout << "qvvr send error ,monitorId is null" << std::endl;
return 1;
}
get_terminal_name_by_terminal_id(dev_id, devname);
get_monitor_name_by_monitor_id(mpid, mpname);
const char* showName_d = devname.empty() ? dev_id.c_str() : devname.c_str();
const char* showName_m = devname.empty() ? mpid.c_str() : mpname.c_str();
root["monitorId"] = mpid;
root["devId"] = dev_id;
root["CpuNo"] = monitor_id;
@@ -1244,10 +1455,18 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
root["eventType"] = dis_kind;
// 时间处理
time_t start_sec = start_tm / 1000; //毫秒级取秒
/*time_t start_sec = start_tm / 1000; //毫秒级取秒
struct tm* time_info = localtime(&start_sec);
char time_buf[32];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", time_info);
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", time_info);*/
time_t start_sec = start_tm / 1000;
struct tm tm_info;
localtime_r(&start_sec, &tm_info);
char time_buf[32];
strftime(time_buf, sizeof(time_buf), "%Y-%m-%d %H:%M:%S", &tm_info);
std::ostringstream start_time_stream;
start_time_stream << time_buf << "." << std::setfill('0') << std::setw(3) << (start_tm % 1000);//构造成年月日时分秒.毫秒
std::string start_time_str = start_time_stream.str();
@@ -1268,10 +1487,28 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
if (!response.empty()) {
try {
json j_r = json::parse(response);
// 有效响应,略过
// =====【新增:业务失败也当异常处理】=====
if (j_r.contains("code")
&& j_r["code"].is_string()
&& j_r["code"].get<std::string>() != "A0000") {
DIY_ERRORLOG_CODE(mpid.c_str(),2,LOG_CODE_TRANSIENT_COMM,"暂态接口业务失败(code=%s),无法上送暂态事件",j_r["code"].get<std::string>().c_str());
std::cout << "qvvr send fail ,store in local" << std::endl;
std::string qvvrDir = FRONT_PATH + "/dat/qvvr/";
std::string fileName = qvvrDir + dev_id + "-" +
std::to_string(monitor_id) + "-" +
FormatTimeForFilename(start_time_str) + "-" +
std::to_string(dis_kind) + ".txt";
writeJsonToFile(fileName, json_string);
checkAndRemoveOldestIfNeeded(qvvrDir, 10LL * 1024 * 1024);
}
// =====【新增结束】=====
} catch (...) {
// 响应异常,保存 json
DIY_ERRORLOG(mpid.c_str(), "【ERROR】暂态接口响应异常,无法上送装置%s监测点%s的暂态事件",dev_id, monitor_id);
DIY_ERRORLOG_CODE(mpid.c_str(),2,LOG_CODE_JSON, "暂态接口响应异常,无法上送暂态事件");
std::cout << "qvvr send fail ,store in local" << std::endl;
std::string qvvrDir = FRONT_PATH + "/dat/qvvr/";
@@ -1281,7 +1518,7 @@ int transfer_json_qvvr_data(const std::string& dev_id, ushort monitor_id,
}
} else {
// 无响应,保存 json
DIY_ERRORLOG(mpid.c_str(), "【ERROR】暂态接口无响应,无法上送装置%s监测点%s的暂态事件",dev_id, monitor_id);
DIY_ERRORLOG_CODE(mpid.c_str(),2,LOG_CODE_TRANSIENT_COMM,"暂态接口无响应,无法上送暂态事件");
std::cout << "qvvr send fail ,store in local" << std::endl;
std::string qvvrDir = FRONT_PATH + "/dat/qvvr/";
@@ -1377,5 +1614,88 @@ bool get_monitor_id_by_dev_and_seq(const std::string& terminal_id,
return false;
}
//////////////////////////////////////////////////////////////////////////
static std::string normalize_id(std::string s)
{
// 去首尾空白和 CRLF
auto is_space = [](char c) {
return c == ' ' || c == '\t' || c == '\r' || c == '\n';
};
// trim left
size_t start = 0;
while (start < s.size() && is_space(s[start])) ++start;
// trim right
size_t end = s.size();
while (end > start && is_space(s[end - 1])) --end;
s = s.substr(start, end - start);
// 如有需要可统一大小写terminal_id 一般是 hex
// std::transform(s.begin(), s.end(), s.begin(), ::tolower);
return s;
}
bool get_terminal_name_by_terminal_id(const std::string& terminal_id,
std::string& out_terminal_name)
{
std::string key = normalize_id(terminal_id);
std::lock_guard<std::mutex> lk(ledgermtx);
for (const auto& dev : terminal_devlist) {
std::string dev_id = normalize_id(dev.terminal_id);
if (dev_id == key) {
out_terminal_name = dev.terminal_name;
return true;
}
}
// ❌ 没找到,打印诊断日志(只在失败时)
std::ostringstream oss;
oss << "terminal_id not found: '" << terminal_id
<< "' (normalized='" << key << "'), existing ids: ";
int cnt = 0;
for (const auto& dev : terminal_devlist) {
if (cnt++ >= 5) { oss << "..."; break; } // 防止日志过长
oss << "'" << dev.terminal_id << "' ";
}
std::cerr << "[LEDGER] " << oss.str() << std::endl;
out_terminal_name.clear();
return false;
}
bool get_monitor_name_by_monitor_id(const std::string& monitor_id,
std::string& out_monitor_name)
{
std::string key = normalize_id(monitor_id);
std::lock_guard<std::mutex> lk(ledgermtx);
for (const auto& dev : terminal_devlist) {
for (const auto& mon : dev.line) {
std::string mon_id = normalize_id(mon.monitor_id);
if (mon_id == key) {
out_monitor_name = mon.monitor_name;
return true;
}
}
}
// ❌ 诊断输出
std::ostringstream oss;
oss << "monitor_id not found: '" << monitor_id
<< "' (normalized='" << key << "')";
std::cerr << "[LEDGER] " << oss.str() << std::endl;
out_monitor_name.clear();
return false;
}

View File

@@ -10,6 +10,8 @@
#include <sstream>
#include <iostream>
#include <unordered_set>
///////////////////////////////////////////////////////////////////////////////////////////
#include "nlohmann/json.hpp"
@@ -44,7 +46,8 @@ public:
class RecallMonitor
{
public:
int recall_status; //补招状态 0-未补招 1-补招中 2-补招完成 3-补招失败
std::string recall_guid; // 本次补招的唯一标识 GUID
int recall_status; //补招状态 0-未补招 1-补招中 2-补招完成 3-补招失败 4-无数据
std::string StartTime; //数据补招起始时间
std::string EndTime; //数据补招结束时间
std::string STEADY; //补招历史统计数据标识 0-不补招1-补招
@@ -68,6 +71,7 @@ enum class ActionResult {
class RecallFile
{
public:
std::string recall_guid; // 本次补招的唯一标识 GUID
int recall_status; // 补招状态 0-未补招 1-补招中 2-补招完成 3-补招失败
std::string StartTime; // 数据补招起始时间yyyy-MM-dd HH:mm:ss
std::string EndTime; // 数据补招结束时间yyyy-MM-dd HH:mm:ss
@@ -76,15 +80,13 @@ public:
//暂态文件用
bool direct_mode = false; // 直下文件开关true 表示不按时间窗,仅按目标文件名
std::string target_filename; // 直下文件名(不含目录)
std::list<std::string> file_paths; // 已下载/要上报的完整路径(用于最终结果)
std::string target_filetimes; // 直下文件匹配时间点yyyyMMdd_HHmmss仅 direct_mode=true 时有效
// ★新增:按“目录名 -> 文件名列表”的映射;由“其他线程”在目录请求成功后回填
std::map<std::string, std::vector<tag_dir_info>> dir_files;
// ★新增:候选目录(可扩展)
std::vector<std::string> dir_candidates{
std::vector<std::string> dir_candidates{
"/cf/COMTRADE",
"/bd0/COMTRADE",
"/sd0/COMTRADE",
@@ -101,9 +103,12 @@ public:
ActionResult download_result = ActionResult::PENDING; // 当前文件的下载结果
// ★新增:下载队列(已筛选出在时间窗内的文件,含完整路径)
std::list<std::string> download_queue;
std::list<std::string> download_queue; //一个时间可能对应多个文件
std::string downloading_file; // 当前正在下载的文件(完整路径)
std::unordered_set<std::string> required_files; // 本次应当下载成功的文件全集
std::unordered_set<std::string> file_success; // 已下载成功的文件集合
// ★新增:一个便捷复位
void reset_runtime(bool keep_direct = false)
{
@@ -115,10 +120,14 @@ public:
download_queue.clear();
downloading_file.clear();
dir_files.clear();
required_files.clear();
file_success.clear();
// ★新增:按需保留直下文件开关和目标名
if (!keep_direct) {
direct_mode = false;
target_filename.clear();
target_filetimes.clear(); // ▲列表清空
}
}
};
@@ -127,7 +136,8 @@ enum class RecallStatus {
NOT_STARTED = 0, // 未补招
RUNNING = 1, // 补招中
DONE = 2, // 补招完成
FAILED = 3 // 补招失败
FAILED = 3, // 补招失败
EMPTY = 4 // 无补招数据
};
// 本轮要下发的一条任务(每个终端最多一条)
@@ -154,6 +164,7 @@ public:
class qvvr_data
{
public:
bool is_pair;
bool used_status; //是否占用
int QVVR_type; //暂态类型
uint64_t QVVR_time; //暂态开始时间 unsigned longlong
@@ -193,6 +204,7 @@ public:
std::string terminal_connect; //监测点接线方式
std::string timestamp; //更新时间
std::string status; //监测点状态
std::string LineLogLevel; //监测点日志级别
double PT1; // 电压变比1
double PT2; // 电压变比2
double CT1; // 电流变比1
@@ -206,6 +218,7 @@ class update_dev
public:
std::string guid; // ★新增:供发送回复使用
std::string DevLogLevel; //装置日志级别
std::string terminal_id;
std::string terminal_name;
std::string org_name;
@@ -239,6 +252,7 @@ public:
std::string logical_device_seq; //监测点序号
std::string voltage_level; //监测点电压等级
std::string terminal_connect; //监测点接线方式
std::string LineLogLevel; //监测点日志级别
std::string timestamp; //更新时间
std::string status; //监测点状态
double PT1; // 电压变比1
@@ -275,6 +289,8 @@ public:
std::vector<NameFixValue> dz_internal_info_list; //内部定值信息列表
std::vector<DZ_kzz_bit> control_words;
std::string DevLogLevel; //装置日志级别
std::string terminal_id;
std::string terminal_name;
std::string org_name;
@@ -671,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);
@@ -702,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);
@@ -718,13 +734,18 @@ void on_device_response_minimal(int response_code,
bool get_monitor_id_by_dev_and_seq(const std::string& terminal_id,
unsigned short logical_seq,
std::string& out_monitor_id);
bool get_monitor_name_by_monitor_id(const std::string& monitor_id,
std::string& out_monitor_name);
bool get_terminal_name_by_terminal_id(const std::string& terminal_id,
std::string& out_terminal_name);
//处理补招的任务
void check_recall_event();
void check_recall_file();
//补招响应
void send_reply_to_kafka_recall(const std::string& guid, const std::string& step,int code, const std::string& result,const std::string& terminalId,const std::string& lineIndex,const std::string& recallStartDate,const std::string& recallEndDate);
void send_reply_to_kafka_recall(const std::string& guid, int step,int code, const std::string& result,const std::string& terminalId,const std::string& lineIndex,const std::string& recallStartDate,const std::string& recallEndDate);
//缓存目录信息
void filemenu_cache_put(const std::string& dev_id,
@@ -732,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);
@@ -804,6 +828,21 @@ inline void print_terminal(const update_dev& tmnl) { print_terminal_common(tmnl)
inline void print_terminal(const terminal_dev& tmnl) { print_terminal_common(tmnl); }
///////////////////////////////////////////////////////////////////////////////////////////////////////////////小工具
// 小工具:判断 s 是否以 suffix 结尾
inline bool has_suffix(const std::string& s, const std::string& suffix) {
if (suffix.size() > s.size()) return false;
return std::equal(suffix.rbegin(), suffix.rend(), s.rbegin());
}
// 小工具:替换前缀
inline bool replace_prefix(std::string& s, const std::string& from, const std::string& to) {
if (s.rfind(from, 0) == 0) { // 以 from 为前缀
s.replace(0, from.size(), to);
return true;
}
return false;
}
inline std::string trim_cstr(const char* s, size_t n) {
if (!s) return {};
size_t end = 0;
@@ -814,6 +853,15 @@ inline std::string trim_cstr(const char* s, size_t n) {
return out;
}
// 去首尾空格
inline std::string trim_copy(const std::string& s) {
size_t b = s.find_first_not_of(" \t\r\n");
if (b == std::string::npos) return "";
size_t e = s.find_last_not_of(" \t\r\n");
return s.substr(b, e - b + 1);
}
//清洗字符串
inline std::string sanitize(std::string s) {
// 截断第一个 NUL 及其后内容
size_t z = s.find('\0');
@@ -841,6 +889,22 @@ inline std::string now_yyyy_mm_dd_hh_mm_ss() {
return oss.str();
}
// 简单键值提取(兼容半角/全角冒号)
inline bool parse_kv_line(const std::string& line,
const std::string& key,
std::string& out) {
std::string k1 = key + ":";
std::string k2 = key + "";
if (line.compare(0, k1.size(), k1) == 0) {
out = trim_copy(line.substr(k1.size()));
return true;
} else if (line.compare(0, k2.size(), k2) == 0) {
out = trim_copy(line.substr(k2.size()));
return true;
}
return false;
}
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////实时数据用
// === 专用锁 + 数据表(仅管实时 idx 映射) ===
extern std::mutex devidx_lock; // 新锁(不要用 ledgermtx
@@ -895,12 +959,114 @@ enum class ResponseCode : int {
TIMEOUT = 406, // 请求超出了等待时间
INTERNAL_ERROR = 500 // 其他错误
};
inline std::string ResponseCodeToString(int code) {
switch (code) {
case 200: return "请求成功";
case 201: return "请求被接受,开始处理";
case 202: return "请求处理中";
case 400: return "请求失败,参数错误";
case 401: return "未认证或认证错误";
case 402: return "请求被拒绝:正在处理同类命令";
case 403: return "请求被拒绝";
case 404: return "资源不存在";
case 405: return "当前忙,无法响应";
case 406: return "请求超时";
case 500: return "内部错误";
default: return "未知响应码";
}
}
static inline bool is_ok(int rc) { return rc == static_cast<int>(ResponseCode::OK); }
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) -> 文件完整路径
extern std::mutex g_recall_file_mtx;
extern std::map<std::pair<std::string,std::string>, std::string> g_recall_file_index;
// 初始化 / 追加 / 删除
bool init_recall_record_file(const std::string& guid,
const std::string& terminalId,
const std::string& monitorId,
const std::string& start,
const std::string& end);
bool append_recall_record_line(const std::string& guid,
const std::string& monitorId,
const std::string& msg);
bool delete_recall_record_file(const std::string& guid,
const std::string& monitorId);
bool get_recall_record_fields_by_guid_monitor(const std::string& guid,
const std::string& monitorId,
std::string& outGuid,
std::string& terminalId,
std::string& outMonitorId,
std::string& startTime,
std::string& endTime,
std::string& msg);
bool SendFileWebAuto(const std::string& id,
const std::string& local_path,
const std::string& remote_path,
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

@@ -17,7 +17,9 @@
#include <vector>
#include <array>
#include <fnmatch.h>
#include <unordered_map>
#include <chrono>
#include <memory>
//////////////////////////////////////////////////////////////////////////////////////////////////////////
#include "log4cplus/logger.h"
#include "log4cplus/configurator.h"
@@ -49,8 +51,45 @@ 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;
static const int LOGTYPE_WILDCARD = 999; // logtype 通配号码
static const char* ID_WILDCARD = "all"; // id 通配字段
std::map<std::string, TypedLogger> logger_map;
DebugSwitch g_debug_switch;
/////////////////////////////////////////////////
// 原子指针append 线程只读它,不加锁
std::shared_ptr<LogLevelCache> g_level_cache_sp;
///////////////////////////////////////////////////////////////
//用来控制日志上送的结构
struct LOGEntry {
std::string id; //测点和装置需要的id
std::string level; // terminal / measurepoint /process
int logtype; // 日志类型
int min_grade; // DEBUG / INFO / WARN / ERROR
int countdown; // 倒计时,单位秒
};
//日志上送map管理
std::map<std::string, LOGEntry> g_log_entries;
pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER;
/////////////////////////////////////////////////////////////////////
std::string build_debug_key(const std::string& id, const std::string& level, int logtype);
//////////////////////////////////////////////////////////
/* log4.cpp 顶部 */
#if __cplusplus >= 201103L
thread_local int g_log_code_tls = 0;
#else
@@ -61,16 +100,35 @@ extern std::string G_LOG_TOPIC;
// 递归创建目录
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;
}
}
}
}
}
@@ -94,6 +152,26 @@ std::string get_level_str(int level) {
default: return "UNKNOWN";
}
}
const char* loglevel_to_str(int lv) {
switch (lv) {
case DEBUG_LOG_LEVEL: return "DEBUG";
case INFO_LOG_LEVEL: return "NORMAL";
case WARN_LOG_LEVEL: return "WARN";
case ERROR_LOG_LEVEL: return "ERROR";
default: return "UNKNOWN";
}
}
static int str_to_loglevel(const std::string& s, int default_level = WARN_LOG_LEVEL)
{
if (s == "DEBUG") return DEBUG_LOG_LEVEL;
if (s == "NORMAL") return INFO_LOG_LEVEL; // NORMAL 当 INFO
if (s == "INFO") return INFO_LOG_LEVEL;
if (s == "WARN") return WARN_LOG_LEVEL;
if (s == "ERROR") return ERROR_LOG_LEVEL;
return default_level; // 空/非法都兜底
}
//////////////////////////////////////////////////////////////////////
TypedLogger::TypedLogger() {}
TypedLogger::TypedLogger(const Logger& l, int t) : logger(l), logtype(t) {}
@@ -121,18 +199,266 @@ bool DebugSwitch::match(const std::string& logger_name, int level, int logtype)
}
return false;
}
////////////////////////////////////////////////////////////////////////////////////
static LogLevelCache* build_cache_unlocked()
{
LogLevelCache* nc = new LogLevelCache;
nc->term_min.reserve(terminal_devlist.size());
std::map<std::string, TypedLogger> logger_map;
DebugSwitch g_debug_switch;
for (const terminal_dev& t : terminal_devlist) {
const int t_lv = str_to_loglevel(t.DevLogLevel, WARN_LOG_LEVEL);
if (!t.terminal_id.empty())
nc->term_min[t.terminal_id] = t_lv;
for (const ledger_monitor& m : t.line) {
if (m.monitor_id.empty()) continue;
// 监测点优先;空/非法自动兜底到终端 t_lv
const int m_lv = str_to_loglevel(m.LineLogLevel, t_lv);
nc->mp_min[m.monitor_id] = m_lv;
}
}
return nc;
}
void refresh_log_level_cache_locked()
{
std::shared_ptr<LogLevelCache> nc(build_cache_unlocked());
std::atomic_store_explicit(&g_level_cache_sp, nc, std::memory_order_release);
}
//////////////////////////////////////////////////////////////////////////////////
class SendAppender : public Appender {
private:
/*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
static std::mutex s_rate_mutex;
// 定义“同一条日志”的规则logger + level + code + msg //原来只区分了日志登记名和等级,现在具体到每一条日志
static std::string make_key(const std::string& logger_name, int level, int code, const std::string& msg) {
std::ostringstream oss;
oss << logger_name << "|" << level << "|" << code << "|" << msg;
return oss.str();
}
// 前 3 次1 秒一次;第 3 次起300 秒一次,一小时恢复
/*static bool should_emit(const std::string& key) {
using namespace std::chrono;
const auto now = steady_clock::now();
std::lock_guard<std::mutex> lk(s_rate_mutex);
RateState& st = s_rate_map[key];
// 超过恢复时间,重置计数
const int RESET_SEC = 3600; // 一小时
if (st.last_emit != steady_clock::time_point::min()) {
auto idle = duration_cast<seconds>(now - st.last_emit).count();
if (idle >= RESET_SEC) {
st.hit_count = 0; // 恢复为“新日志”
}
}
st.hit_count++;
const int period_sec = (st.hit_count > 3) ? 300 : 1;
if (st.last_emit == steady_clock::time_point::min()) {
st.last_emit = now;
return true;
}
const auto elapsed = duration_cast<seconds>(now - st.last_emit).count();
if (elapsed >= period_sec) {
st.last_emit = now;
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;
}
static bool find_entry_allow(const std::string& key, int level_val) { //通配方式查找
std::map<std::string, LOGEntry>::iterator it = g_log_entries.find(key);
if (it == g_log_entries.end() || it->second.countdown <= 0) return false;
return level_val >= it->second.min_grade;
}
static bool allow_low_level_send(const std::string& id,
const std::string& level_str,//层级
int logtype,
int level_val) {//告警等级
pthread_mutex_lock(&g_log_mutex);
// 1) 精确匹配id + level + logtype //这个id指定日志种类指定级别的日志
if (find_entry_allow(build_debug_key(id, level_str, logtype), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 2) logtype 通配id + level + -1 //这个id指定日志级别的所有日志
if (find_entry_allow(build_debug_key(id, level_str, LOGTYPE_WILDCARD), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 3) id 通配:* + level + logtype //这个id的指定级别的日志
if (find_entry_allow(build_debug_key(ID_WILDCARD, level_str, logtype), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
// 4) 双通配:* + level + -1 //所有指定级别的日志,即根据台账的等级来上送所有日志
if (find_entry_allow(build_debug_key(ID_WILDCARD, level_str, LOGTYPE_WILDCARD), level_val)) {
pthread_mutex_unlock(&g_log_mutex);
return true;
}
pthread_mutex_unlock(&g_log_mutex);
return false;
}
////////////////////////////////////////////////////////////////添加台账日志控制
static int get_min_send_level_cached(const std::string& level_str, const std::string& logger_name)
{
const int DEFAULT_LEVEL = WARN_LOG_LEVEL;
if (level_str == "process") return DEFAULT_LEVEL;
const std::string id = extract_logger_id(logger_name);
if (id.empty()) return DEFAULT_LEVEL;
std::shared_ptr<LogLevelCache> c =
std::atomic_load_explicit(&g_level_cache_sp, std::memory_order_acquire);
if (!c) return DEFAULT_LEVEL;
if (level_str == "terminal") {
auto it = c->term_min.find(id);
return (it != c->term_min.end()) ? it->second : DEFAULT_LEVEL;
}
if (level_str == "measurepoint") {
auto it = c->mp_min.find(id);
return (it != c->mp_min.end()) ? it->second : DEFAULT_LEVEL;
}
return DEFAULT_LEVEL;
}
protected:
void append(const spi::InternalLoggingEvent& event) {
void append(const spi::InternalLoggingEvent& event) override {
std::string logger_name = event.getLoggerName();
int level = event.getLogLevel();
std::string msg = event.getMessage();
int logtype = (logger_name.find(".COM") != std::string::npos) ? LOGTYPE_COM : LOGTYPE_DATA;
std::string level_str;
if (logger_name.find("process") == 0)
level_str = "process";
@@ -141,76 +467,118 @@ protected:
else
level_str = "terminal";
// ★读取 TLS 中的 code(在打日志的线程里由宏设定)
int code = g_log_code_tls; // 若未显式传入,则为 0
// TLS code
int code = g_log_code_tls;
if (level == ERROR_LOG_LEVEL || level == WARN_LOG_LEVEL || g_debug_switch.match(logger_name, level, logtype)) {
std::ostringstream oss;
oss << "{\"processNo\":\"" << std::to_string(g_front_seg_index)
<< "\",\"nodeId\":\"" << FRONT_INST
<< "\",\"businessId\":\"" << extract_logger_id(logger_name)
<< "\",\"level\":\"" << level_str
<< "\",\"time\":\"" << now_yyyy_mm_dd_hh_mm_ss()
<< "\",\"grade\":\"" << get_level_str(level)
// ★新增:输出 code 字段(整型)
<< "\",\"code\":\"" << code
<< "\",\"log\":\"" << escape_json(msg) << "\"}";
const int safe_logtype = code; // 使用 code 作为 logtype
std::string jsonString = oss.str();
bool allow_send = false;
queue_data_t connect_info;
connect_info.strTopic = G_LOG_TOPIC;
connect_info.strText = jsonString;
connect_info.tag = G_LOG_TAG;
connect_info.key = G_LOG_KEY;
int min_send_level = get_min_send_level_cached(level_str, logger_name);
std::lock_guard<std::mutex> lock(queue_data_list_mutex);
queue_data_list.push_back(connect_info);
std::cout << "[LOG] logger: " << logger_name
<< ", level_str: " << level_str
<< ", level: " << level
<< ", min_send_level: " << min_send_level << std::endl;
// ① 高于“台账阈值”的日志:直接上送
if (level >= min_send_level) {
allow_send = true;
} else {
// NORMAL/DEBUG 默认不上送,必须命令打开
std::string ctrl_level = level_str; // "process" / "terminal" / "measurepoint"
std::string ctrl_id;
if (ctrl_level == "process") {
ctrl_id = "process"; // process 用固定 id
} else {
ctrl_id = extract_logger_id(logger_name); // terminal.<id> / monitor.<id>
if (ctrl_id.empty()) {
// 没解析出 id就不给低等级上送避免误发
allow_send = false;
}
}
if (!ctrl_id.empty()) {
allow_send = allow_low_level_send(ctrl_id, ctrl_level, safe_logtype, level);
}
}
if (!allow_send) {
return;
}
// ★新增:限频判断(同一条日志前 5 次 1 秒一次;之后 300 秒一次)
const std::string key = make_key(logger_name, level, code, msg);
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;
oss << "{\"processNo\":\"" << std::to_string(g_front_seg_index)
<< "\",\"nodeId\":\"" << FRONT_INST
<< "\",\"businessId\":\"" << extract_logger_id(logger_name)
<< "\",\"level\":\"" << level_str
<< "\",\"time\":\"" << now_yyyy_mm_dd_hh_mm_ss()
<< "\",\"grade\":\"" << get_level_str(level)
// ★建议code 用数字(不是字符串)
<< "\",\"code\":" << code
<< ",\"log\":\"" << escape_json(final_msg) << "\"}";
queue_data_t connect_info;
connect_info.strTopic = G_LOG_TOPIC;
connect_info.strText = oss.str();
connect_info.tag = G_LOG_TAG;
connect_info.key = G_LOG_KEY;
std::lock_guard<std::mutex> lock(queue_data_list_mutex);
queue_data_list.push_back(connect_info);
}
std::string escape_json(const std::string& input) {
std::ostringstream ss;
for (unsigned int i = 0; i < input.size(); ++i) {
for (size_t i = 0; i < input.size(); ++i) {
switch (input[i]) {
case '\\': ss << "\\\\"; break;
case '"': ss << "\\\""; break;
case '\n': ss << "\\n"; break;
case '\r': ss << "\\r"; break;
case '\t': ss << "\\t"; break;
default: ss << input[i]; break;
case '"': ss << "\\\""; break;
case '\n': ss << "\\n"; break;
case '\r': ss << "\\r"; break;
case '\t': ss << "\\t"; break;
default: ss << input[i]; break;
}
}
return ss.str();
}
virtual void close() {
void close() override {
// 可空实现
}
public:
SendAppender() {}
virtual ~SendAppender() {
destructorImpl(); // 重要!释放 log4cplus 基类资源
destructorImpl();
}
};
//用来控制日志上送的结构
struct LOGEntry {
std::string id;
std::string level; // terminal / measurepoint
int logtype; // com / data
int min_grade;
int countdown;
};
//日志上送map管理
std::map<std::string, LOGEntry> g_log_entries;
pthread_mutex_t g_log_mutex = PTHREAD_MUTEX_INITIALIZER;
//用来控制日志上送的静态变量定义
std::unordered_map<std::string, SendAppender::RateState> SendAppender::s_rate_map;
std::mutex SendAppender::s_rate_mutex;
// 生成唯一 key
std::string build_debug_key(const std::string& id, const std::string& level, int logtype) {
return id + "|" + level + "|" + (logtype == 1 ? "COM" : "DATA");
std::ostringstream oss;
oss << id << "|" << level << "|" << logtype;
return oss.str();
}
// 外部线程中调用每秒更新所有倒计时0 则删除
@@ -231,20 +599,19 @@ void update_log_entries_countdown() {
pthread_mutex_unlock(&g_log_mutex);
}
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, const std::string& logtype_str) {
if (level != "terminal" && level != "measurepoint") return;
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, int logtype) {
if (level != "terminal" && level != "measurepoint" && level != "process") return;
int type = (logtype_str == "com") ? LOGTYPE_COM : LOGTYPE_DATA;
int grade_level = (grade == "DEBUG") ? DEBUG_LOG_LEVEL : INFO_LOG_LEVEL;
std::string key = build_debug_key(id, level, type);
std::string key = build_debug_key(id, level, logtype);
pthread_mutex_lock(&g_log_mutex);
LOGEntry& entry = g_log_entries[key]; // 会自动 insert 或取已有
entry.id = id;
entry.level = level;
entry.logtype = type;
entry.logtype = logtype;
entry.min_grade = grade_level;
entry.countdown = 60; // 重置倒计时
@@ -283,7 +650,7 @@ log4cplus::Logger init_logger(const std::string& full_name,
//进程的日志
void init_logger_process() {
std::string base_dir = FRONT_PATH + "/" + subdir + "/processNo" + std::to_string(g_front_seg_index) + "/log";
logger_map["process"] = TypedLogger(init_logger(std::string("process"), base_dir, std::string("process")), LOGTYPE_DATA);
logger_map["process"] = TypedLogger(init_logger(std::string("process"), base_dir, std::string("process")), LOGTYPE_DEFAULT);
std::cout << "process log init ok" << std::endl;
}
@@ -314,7 +681,7 @@ void init_loggers_bydevid(const std::string& dev_id)
// 添加判断:终端日志 logger 是否已存在
if (logger_map.find(device_key) == logger_map.end()) {
// 所有终端日志com 和 data写到同一个 device 日志文件中
// 所有终端日志写到同一个 device 日志文件中
std::string file_path_t = device_dir + "/" + dev_id + ".log";
// 共用一个 appender 实例
@@ -322,9 +689,9 @@ void init_loggers_bydevid(const std::string& dev_id)
device_appender->setLayout(std::unique_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
Logger device_logger = init_logger(device_key, device_dir, dev_id, device_appender);
logger_map[device_key] = TypedLogger(device_logger, LOGTYPE_DATA);
logger_map[device_key] = TypedLogger(device_logger, LOGTYPE_DEFAULT);
//DIY_WARNLOG(dev_id.c_str(), "【WARN】终端id:%s终端级日志初始化完毕", term.terminal_id.c_str());
}
// 初始化监测点日志monitor.<mp_id>.COM / .DATA
@@ -347,9 +714,9 @@ void init_loggers_bydevid(const std::string& dev_id)
monitor_appender->setLayout(std::unique_ptr<Layout>(new PatternLayout("%D{%Y-%m-%d %H:%M:%S} [%p] [%c] %m%n")));
Logger mon_logger = init_logger(mon_key.str(), mon_path.str(), mon_name.str(), monitor_appender);
logger_map[mon_key.str()] = TypedLogger(mon_logger, LOGTYPE_DATA);
logger_map[mon_key.str()] = TypedLogger(mon_logger, LOGTYPE_DEFAULT);
//DIY_WARNLOG(monitor.monitor_id.c_str(), "【WARN】监测点:%s - id:%s监测点级日志初始化完毕", monitor.monitor_name.c_str(), monitor.logical_device_seq.c_str());
}
}
}
@@ -387,9 +754,9 @@ void init_loggers()
Logger device_logger = init_logger(device_key, device_dir, term.terminal_id, device_appender);
logger_map[device_key] = TypedLogger(device_logger, LOGTYPE_DATA);
logger_map[device_key] = TypedLogger(device_logger, LOGTYPE_DEFAULT);
//DIY_WARNLOG(term.terminal_id.c_str(), "【WARN】终端id:%s终端级日志初始化完毕", term.terminal_id.c_str());
// 初始化监测点日志
for (size_t i = 0; i < term.line.size(); ++i) {
@@ -410,10 +777,9 @@ void init_loggers()
Logger mon_logger = init_logger(mon_key.str(), mon_path.str(), mon_name.str(), monitor_appender);
logger_map[mon_key.str()] = TypedLogger(mon_logger, LOGTYPE_DATA);
logger_map[mon_key.str()] = TypedLogger(mon_logger, LOGTYPE_DEFAULT);
//DIY_WARNLOG(mon_key.str().c_str(), "【WARN】监测点:%s - id:%s监测点级日志初始化完毕",
//monitor.monitor_name.c_str(), monitor.logical_device_seq.c_str());
}
}
}
@@ -463,7 +829,11 @@ extern "C" {
// 公共函数
void log4_log_with_level(const char* key, const char* msg, int level) {
std::map<std::string, TypedLogger>::iterator it = logger_map.find(key);
if (it == logger_map.end()) return;
if (it == logger_map.end()) {
std::cout << "[LOG][MISS] logger not found, key="
<< (key ? key : "NULL") << std::endl;
return;
}
Logger logger = it->second.logger;
switch (level) {
@@ -484,6 +854,7 @@ extern "C" {
//标准化日志接口
// #define LOGMSG_WITH_TS // 需要时间时再打开
//已在头文件添加编译校验
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...) {
if (!buf || buf_size == 0) return;
buf[0] = '\0';

View File

@@ -32,9 +32,22 @@ extern LOG_TLS_SPEC int g_log_code_tls;
#include "appender.h"
#define LOGTYPE_COM 1
#define LOGTYPE_DATA 2
/////////////////////////////////////////////入参验证
#if defined(__GNUC__) || defined(__clang__)
# define PRINTF_LIKE(fmt_index, first_arg) __attribute__((format(printf, fmt_index, first_arg)))
#else
# define PRINTF_LIKE(fmt_index, first_arg)
#endif
/////////////////////////////////////////
struct LogLevelCache { //日志等级缓存
// terminal_id -> min_level
std::unordered_map<std::string, int> term_min;
// monitor_id -> min_level
std::unordered_map<std::string, int> mp_min;
};
////////////////////////////////////
struct TypedLogger {
log4cplus::Logger logger;
int logtype;
@@ -63,9 +76,8 @@ extern DebugSwitch g_debug_switch;
extern void send_reply_to_queue(const std::string& guid, const int code, const std::string& result);
//std::string get_front_type_from_subdir();
extern std::shared_ptr<LogLevelCache> g_level_cache_sp;
const char* loglevel_to_str(int lv);
// 不带 Appender 的版本
log4cplus::Logger init_logger(const std::string& full_name,
@@ -78,11 +90,15 @@ log4cplus::Logger init_logger(const std::string& full_name,
const std::string& base_file,
log4cplus::SharedAppenderPtr fileAppender);
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, const std::string& logtype_str);
void process_log_command(const std::string& id, const std::string& level, const std::string& grade, int logtype);
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);
@@ -94,7 +110,9 @@ void log_debug(const char* key, const char* msg);
void log_info(const char* key, const char* msg);
void log_warn(const char* key, const char* msg);
void log_error(const char* key, const char* msg);
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);
//void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);
//带验证
void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...) PRINTF_LIKE(3,4);
// ====================== ★新增:线程局部变量透传 code ======================
// 说明:使用编译器的 TLS__thread保存当前日志的 code 值。
@@ -104,20 +122,28 @@ void format_log_msg(char* buf, size_t buf_size, const char* fmt, ...);
// ====================== ★新增结束 ======================
typedef enum LogCode {
LOG_CODE_WIRETYPE = 96, /* 接线类型 */
LOG_CODE_CONFIG = 97, /* 配置相关 */
LOG_CODE_JSON = 98, /* JSON结构 */
LOG_CODE_OTHER = 99, /* 其他类型 */
LOG_CODE_LEDGER = 100, /* 台账类型 */
LOG_CODE_RPTINIT = 101, /* 报告初始化 */
LOG_CODE_ICD_AND_DOWNLOAD = 200, /* ICD 和文件下载类型 */
LOG_CODE_ICD_AND_DOWNLOAD = 200, /* ICD 类型 */
LOG_CODE_TRANSIENT = 300, /* 暂态发生 */
LOG_CODE_TRANSIENT_COMM = 301, /* 暂态接口 */
LOG_CODE_COMTRADE_FILE = 302, /* 录波文件Comtrade */
LOG_CODE_FILE = 302, /* 文件上传 */
LOG_CODE_MQ = 400, /* MQ发送 */
LOG_CODE_RT_DATA = 401, /* 实时数据 */
LOG_CODE_LEDGER_UPDATE = 402, /* 台账更新 */
LOG_CODE_PROCESS_CONTROL = 403, /* 进程控制 */
LOG_CODE_RECALL = 404, /* 补招相关 */
LOG_CODE_LOG_REQUEST = 405, /* 日志请求 */
LOG_CODE_CLOUD = 406, /* 云前置控制 */
LOG_CODE_REPORT = 500, /* 报告处理 */
LOG_CODE_COMM = 600, /* 通讯状态 */
LOG_CODE_SPACE_ALARM = 700, /* 空间告警 */
LOG_CODE_DEV_ALARM = 800 /* 设备告警 */
@@ -175,7 +201,7 @@ typedef enum LogCode {
#define DIY_DEBUGLOG(KEY, ...) DIY_LOG_CODE(log_debug, KEY, 0, LOG_CODE_OTHER,__VA_ARGS__) // ★修改:默认 code=0
// ★新增:显式传入 code 的便捷宏
// 用法示例DIY_WARNLOG_CODE(full_key_m_c, warn_recallstart, "【WARN】监测点:%s ...", ...);
// 用法示例DIY_WARNLOG_CODE(full_key_m_c, warn_recallstart, "监测点:%s ...", ...);
#define DIY_ERRORLOG_CODE(KEY, LEVEL_INT,CODE_INT, ...) DIY_LOG_CODE(log_error, KEY, LEVEL_INT, CODE_INT, __VA_ARGS__) // ★新增
#define DIY_WARNLOG_CODE(KEY, LEVEL_INT,CODE_INT, ...) DIY_LOG_CODE(log_warn, KEY, LEVEL_INT, CODE_INT, __VA_ARGS__) // ★新增
#define DIY_INFOLOG_CODE(KEY, LEVEL_INT,CODE_INT, ...) DIY_LOG_CODE(log_info, KEY, LEVEL_INT, CODE_INT, __VA_ARGS__) // ★新增

View File

@@ -37,7 +37,27 @@
#include "rocketmq/MQClientException.h"
#include "front.h"
//////////////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////////////命名空间
//lnk 20251211
namespace {
std::mutex g_streamMutex;
void safe_out_str(const std::string& s) {
std::lock_guard<std::mutex> lk(g_streamMutex);
std::cout << s << std::flush;
}
void safe_out_line(const std::string& s) {
std::lock_guard<std::mutex> lk(g_streamMutex);
std::cout << s << std::endl;
}
void safe_err_line(const std::string& s) {
std::lock_guard<std::mutex> lk(g_streamMutex);
std::cerr << s << std::endl;
}
}
using json = nlohmann::json;
@@ -49,7 +69,7 @@ std::string FRONT_PATH;
//初始化标志
int INITFLAG = 0;
std::atomic<int> INITFLAG{0};
//前置标置
std::string subdir = "cloudfrontproc"; //子目录
@@ -85,6 +105,18 @@ std::unique_ptr<T> make_unique(Args&&... args) {
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
}
// 把“今天”做成年月日整数YYYYMMDD用于“每天只清理一次”的判定
static inline int local_ymd_today() {
std::time_t now = std::time(nullptr);
std::tm local_tm{};
#if defined(_WIN32) || defined(_WIN64)
localtime_s(&local_tm, &now);
#else
local_tm = *std::localtime(&now);
#endif
return (local_tm.tm_year + 1900) * 10000 + (local_tm.tm_mon + 1) * 100 + local_tm.tm_mday;
}
//处理参数
bool parse_param(int argc, char* argv[]) {
for (int i = 1; i < argc; ++i) {
@@ -138,35 +170,6 @@ bool parse_param(int argc, char* argv[]) {
return true;
}
//获取前置类型
/*void init_global_function_enable() {
if (subdir == "cfg_stat_data") { // 历史稳态
g_node_id = STAT_DATA_BASE_NODE_ID;
auto_register_report_enabled = 1;
} else if (subdir == "cfg_3s_data") { // 实时
g_node_id = THREE_SECS_DATA_BASE_NODE_ID;
three_secs_enabled = 1;
} else if (subdir == "cfg_soe_comtrade") { // 告警、录波、暂态
g_node_id = SOE_COMTRADE_BASE_NODE_ID;
} else if (subdir == "cfg_recallhis_data") { // 补招
g_node_id = RECALL_HIS_DATA_BASE_NODE_ID;
}
}*/
//获取功能名称
/*std::string get_front_msg_from_subdir() {
if (subdir.find("cfg_3s_data") != std::string::npos)
return "实时数据进程";
else if (subdir.find("cfg_soe_comtrade") != std::string::npos)
return "暂态和告警进程";
else if (subdir.find("cfg_recallhis_data") != std::string::npos)
return "稳态补招进程";
else if (subdir.find("cfg_stat_data") != std::string::npos)
return "稳态统计进程";
else
return "unknown";
}*/
//获取前置路径
std::string get_parent_directory() {
// 获取当前工作目录
@@ -206,7 +209,7 @@ std::string get_parent_directory() {
//启动进程日志
init_logger_process();
DIY_WARNLOG("process","【WARN】前置的%d号进程 进程级日志初始化完毕", g_front_seg_index);
//读取台账
parse_device_cfg_web();
@@ -246,7 +249,7 @@ std::string get_parent_directory() {
}
// ============ 关闭所有运行中的线程============
void Front::FormClosing() {
/*void Front::FormClosing() {
//确保testshell关闭
m_worker.stopServer();
@@ -286,11 +289,19 @@ std::string get_parent_directory() {
m_MQConsumerThread.join();
}
}*/
void Front::FormClosing() {
m_worker.stopServer();
StopFrontThread();
StopTimerThread();
StopMQProducerThread();
StopMQConsumerThread();
}
//============ 线程函数 ============
void Front::StartFrontThread() {
/*void Front::StartFrontThread() {
m_bIsFrontThreadCancle = false;
m_FrontThread = std::thread(&Front::FrontThread, this);
}
@@ -308,26 +319,155 @@ std::string get_parent_directory() {
void Front::StartTimerThread() {
m_IsTimerCancel = false;
m_TimerThread = std::thread(&Front::OnTimerThread, this);
}
} */
void Front::StartFrontThread() {
bool expected = false;
if (!m_frontRunning.compare_exchange_strong(expected, true)) {
std::cout << "[FrontThread] already running, skip\n";
return;
}
if (m_FrontThread.joinable()) m_FrontThread.join();
m_bIsFrontThreadCancle = false;
m_FrontThread = std::thread([this]{
try {
this->FrontThread();
} catch (const std::exception& e) {
std::cerr << "[FrontThread] exception: " << e.what() << "\n";
} catch (...) {
std::cerr << "[FrontThread] unknown exception\n";
}
m_frontRunning = false; // 线程真正退出后复位
});
}
void Front::StartMQConsumerThread() {
bool expected = false;
if (!m_consumerRunning.compare_exchange_strong(expected, true)) {
std::cout << "[MQConsumer] already running, skip\n";
return;
}
if (m_MQConsumerThread.joinable()) m_MQConsumerThread.join();
m_IsMQConsumerCancel = false;
m_MQConsumerThread = std::thread([this]{
try {
this->mqconsumerThread();
} catch (const std::exception& e) {
std::cerr << "[mqconsumerThread] exception: " << e.what() << "\n";
} catch (...) {
std::cerr << "[mqconsumerThread] unknown exception\n";
}
m_consumerRunning = false;
});
}
void Front::StartMQProducerThread() {
bool expected = false;
if (!m_producerRunning.compare_exchange_strong(expected, true)) {
std::cout << "[MQProducer] already running, skip\n";
return;
}
if (m_MQProducerThread.joinable()) m_MQProducerThread.join();
m_IsMQProducerCancel = false;
m_MQProducerThread = std::thread([this]{
try {
this->mqproducerThread();
} catch (const std::exception& e) {
std::cerr << "[mqproducerThread] exception: " << e.what() << "\n";
} catch (...) {
std::cerr << "[mqproducerThread] unknown exception\n";
}
m_producerRunning = false;
});
}
void Front::StartTimerThread() {
bool expected = false;
if (!m_timerRunning.compare_exchange_strong(expected, true)) {
std::cout << "[Timer] already running, skip StartTimerThread\n";
return; // 已有定时线程在跑,直接跳过
}
// 若有旧线程尚未 join先回收
if (m_TimerThread.joinable()) {
m_TimerThread.join();
}
m_IsTimerCancel.store(false, std::memory_order_relaxed);
m_TimerThread = std::thread([this]{
try {
this->OnTimerThread();
} catch (const std::exception& e) {
std::cerr << "[Timer] exception: " << e.what() << "\n";
} catch (...) {
std::cerr << "[Timer] unknown exception\n";
}
m_timerRunning.store(false); // 线程真正退出后复位
});
}
void Front::StopFrontThread() {
if (!m_frontRunning.load()) return;
m_bIsFrontThreadCancle = true;
if (m_FrontThread.joinable()) m_FrontThread.join();
m_frontRunning = false;
}
void Front::StopMQConsumerThread() {
if (!m_consumerRunning.load()) return;
m_IsMQConsumerCancel = true; // 你的线程函数可能不轮询此标志,但先置上
// 关闭 MQ 对象(避免内部阻塞线程仍在)
if (m_mqConsumer) {
try { m_mqConsumer->shutdown(); } catch (...) {}
m_mqConsumer.reset();
}
m_listener.reset();
if (m_MQConsumerThread.joinable()) m_MQConsumerThread.join();
m_consumerRunning = false;
}
void Front::StopMQProducerThread() {
if (!m_producerRunning.load()) return;
m_IsMQProducerCancel = true;
if (m_MQProducerThread.joinable()) m_MQProducerThread.join();
m_producerRunning = false;
// 如需销毁/关闭 producer对应你的初始化方式
// if (m_producer) { ShutdownProducer(m_producer); m_producer = nullptr; }
}
void Front::StopTimerThread() {
if (!m_timerRunning.load()) return; // 没跑就不处理
m_IsTimerCancel.store(true);
if (m_TimerThread.joinable()) {
m_TimerThread.join(); // 等它退出
}
m_timerRunning.store(false);
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////主功能线程
void Front::FrontThread() {
std::cout << "FrontThread::run() is called ...... \n";
safe_out_line("FrontThread::run() is called ...... \n");
try {
while (!m_bIsFrontThreadCancle) {
check_recall_file(); //处理补招文件-稳态和暂态
check_recall_event(); // 处理补招事件从list中读取然后直接调用接口,每一条可能都不同测点,每个测点自己做好记录
//check_ledger_update(); // 触发台账更新
check_recall_file(); //处理补招文件-稳态和暂态
std::this_thread::sleep_for(std::chrono::milliseconds(100));
}
} catch (const std::exception& e) {
std::cerr << "[FrontThread] Caught exception: " << e.what() << std::endl;
safe_err_line(std::string("[FrontThread] Caught exception: ") + e.what());
} catch (...) {
std::cerr << "[FrontThread] Caught unknown exception" << std::endl;
safe_err_line("[FrontThread] Caught unknown exception");
}
// 设置重启标志
@@ -336,7 +476,7 @@ void Front::FrontThread() {
m_needRestartFrontThread = true;
}
std::cout << "[FrontThread] exited, will be restarted by monitor\n";
safe_out_line("[FrontThread] exited, will be restarted by monitor\n");
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////定时任务
@@ -345,16 +485,19 @@ void Front::OnTimerThread()
{
try {
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
std::cout << "OnTimerThread::run() is called ...... \n";
safe_out_line("OnTimerThread::run() is called ...... \n");
int hbCounter = 0; // 心跳计数
int backupCounter = 0; // 备份计数(分钟用)
send_heartbeat_to_queue("1");
//记录“上次做日清理”的日期YYYYMMDD确保每天只做一次
static int s_lastCleanupYMD = -1;
while (!m_IsTimerCancel)
{
update_log_entries_countdown();
update_log_entries_countdown();//日志上送倒计时
//业务超时检查
check_device_busy_timeout();
@@ -371,6 +514,18 @@ void Front::OnTimerThread()
backupCounter = 0;
}
// 按天清理 —— 发现“日期变更”则执行一次清理
{
const int todayYMD = local_ymd_today(); // YYYYMMDD本地时区
if (todayYMD != s_lastCleanupYMD) {
// 说明进入了新的一天:执行清理(删除前日及更早的未配对事件)
safe_out_line("[OnTimerThread] daily cleanup start, today=" + std::to_string(todayYMD) + "\n");
cleanup_old_unpaired_qvvr_events(); // 调用清理内存的暂态事件
s_lastCleanupYMD = todayYMD;
safe_out_line("[OnTimerThread] daily cleanup done\n");
}
}
hbCounter++;
backupCounter++;
@@ -378,9 +533,9 @@ void Front::OnTimerThread()
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}
} catch (const std::exception& e) {
std::cerr << "[OnTimerThread] Caught exception: " << e.what() << std::endl;
safe_err_line(std::string("[OnTimerThread] Caught exception: ") + e.what());
} catch (...) {
std::cerr << "[OnTimerThread] Caught unknown exception" << std::endl;
safe_err_line("[OnTimerThread] Caught unknown exception");
}
{
@@ -388,7 +543,7 @@ void Front::OnTimerThread()
m_needRestartTimerThread = true;
}
std::cout << "[OnTimerThread] exited, will be restarted by monitor\n";
safe_out_line("[OnTimerThread] exited, will be restarted by monitor\n");
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////消费者线程
@@ -410,7 +565,16 @@ 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);
// ✅ 必须在 start() 之前设置
//m_mqConsumer->setLogPath("/data/logs/rocketmq"); // 目录
m_mqConsumer->setLogLevel(rocketmq::eLOG_LEVEL_ERROR); // 级别error
m_mqConsumer->setLogFileSizeAndNum(5, 50); // 5 个文件,每个 50MB
m_mqConsumer->setNamesrvAddr(nameServer);
m_mqConsumer->setSessionCredentials(G_MQCONSUMER_ACCESSKEY, G_MQCONSUMER_SECRETKEY, G_MQCONSUMER_CHANNEL);
m_mqConsumer->setInstanceName("inst_" + std::to_string(sGetMsTime()));
@@ -421,37 +585,37 @@ void Front::mqconsumerThread()
std::string key = sub.topic + ":" + sub.tag;
callbackMap.emplace(key, sub.callback);
m_mqConsumer->subscribe(sub.topic, sub.tag);
std::cout << "[mqconsumerThread] 已订阅 Topic=\"" << sub.topic << "\", Tag=\"" << sub.tag << "\"" << std::endl;
safe_out_line("[mqconsumerThread] 已订阅 Topic=\"" + sub.topic + "\", Tag=\"" + sub.tag + "\"\n");
}
m_listener = std::make_shared<rocketmq::SubscriberListener>(callbackMap);
m_mqConsumer->registerMessageListener(m_listener.get());
m_mqConsumer->start();
std::cout << "[mqconsumerThread] Consumer 已启动,等待消息..." << std::endl;
safe_out_line("[mqconsumerThread] Consumer 已启动,等待消息...\n");
// ✳️ 保持线程不主动退出,由 RocketMQ 内部驱动执行回调
// 如果 RocketMQ 内部机制失败或意外退出线程,就走 catch
}
catch (const rocketmq::MQClientException& e) {
std::cerr << "[mqconsumerThread] MQClientException: " << e.what() << std::endl;
safe_err_line(std::string("[mqconsumerThread] MQClientException: ") + e.what());
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartConsumerThread = true;
return;
} catch (const std::exception& e) {
std::cerr << "[mqconsumerThread] std::exception: " << e.what() << std::endl;
safe_err_line(std::string("[mqconsumerThread] std::exception: ") + e.what());
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartConsumerThread = true;
return;
} catch (...) {
std::cerr << "[mqconsumerThread] Unknown exception" << std::endl;
safe_err_line("[mqconsumerThread] Unknown exception");
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartConsumerThread = true;
return;
}
// 程序运行中,消费者会通过回调处理消息,线程保持存活即可
std::cout << "[mqconsumerThread] Consumer 线程正在运行,等待消息到达..." << std::endl;
safe_out_line("[mqconsumerThread] Consumer 线程正在运行,等待消息到达...");
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////生产者线程
@@ -461,7 +625,7 @@ void Front::mqproducerThread()
try {
// 1. 初始化生产者
InitializeProducer(m_producer);
std::cout << "\n[mqproducerThread] is running ...... \n\n";
safe_out_line("\n[mqproducerThread] is running ...... \n\n");
uint32_t count = 0;
@@ -480,49 +644,60 @@ void Front::mqproducerThread()
}
if (data_gotten) {
auto now = std::chrono::system_clock::now();
auto ms_part = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
auto time_t_part = std::chrono::system_clock::to_time_t(now);
std::tm tm_buf;
localtime_r(&time_t_part, &tm_buf);
char timeStr[32];
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf);
{
auto now = std::chrono::system_clock::now();
auto ms_part = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
auto time_t_part = std::chrono::system_clock::to_time_t(now);
std::tm tm_buf;
localtime_r(&time_t_part, &tm_buf);
char timeStr[32];
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf);
std::cout << "BEGIN my_queue_send no." << count
<< " >>>> " << timeStr
<< "." << std::setw(3) << std::setfill('0') << ms_part.count()
<< std::endl;
std::ostringstream oss;
oss << "BEGIN my_queue_send no." << count
<< " >>>> " << timeStr
<< "." << std::setw(3) << std::setfill('0') << ms_part.count();
// 线程安全输出
safe_out_line(oss.str());
}
// 调用实际发送
my_rocketmq_send(data, m_producer);
now = std::chrono::system_clock::now();
ms_part = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
time_t_part = std::chrono::system_clock::to_time_t(now);
localtime_r(&time_t_part, &tm_buf);
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf);
{
auto now = std::chrono::system_clock::now();
auto ms_part = std::chrono::duration_cast<std::chrono::milliseconds>(
now.time_since_epoch()) % 1000;
auto time_t_part = std::chrono::system_clock::to_time_t(now);
std::tm tm_buf;
localtime_r(&time_t_part, &tm_buf);
char timeStr[32];
std::strftime(timeStr, sizeof(timeStr), "%Y-%m-%d %H:%M:%S", &tm_buf);
std::cout << "END my_queue_send no." << count++
<< " >>>> " << timeStr
<< "." << std::setw(3) << std::setfill('0') << ms_part.count()
<< "\n\n";
std::ostringstream oss;
oss << "END my_queue_send no." << count
<< " <<<< " << timeStr
<< "." << std::setw(3) << std::setfill('0') << ms_part.count();
safe_out_line(oss.str());
}
}
g_mqproducer_blocked_times = 0;
std::this_thread::sleep_for(std::chrono::milliseconds(10));
}
std::cout << "[mqproducerThread] 正常退出\n";
safe_out_line("[mqproducerThread] 正常退出\n");
}
catch (const std::exception& e) {
std::cerr << "[mqproducerThread] std::exception: " << e.what() << std::endl;
safe_err_line(std::string("[mqproducerThread] std::exception: ") + e.what());
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartProducerThread = true;
}
catch (...) {
std::cerr << "[mqproducerThread] unknown exception\n";
safe_err_line("[mqproducerThread] unknown exception\n");
std::lock_guard<std::mutex> lock(m_threadCheckMutex);
m_needRestartProducerThread = true;
}
@@ -534,17 +709,18 @@ void Front::mqproducerThread()
extern thread_info_t thread_info[THREAD_CONNECTIONS];
void cleanup_args(ThreadArgs* args) {
/*void cleanup_args(ThreadArgs* args) {
for (int i = 0; i < args->argc; ++i) {
free(args->argv[i]); // strdup 分配的
}
delete[] args->argv;
delete args;
}
}*/
void* cloudfrontthread(void* arg) {
///////////////////////////////////////
ThreadArgs* args = static_cast<ThreadArgs*>(arg);
//不再需要入参20251208
/*ThreadArgs* args = static_cast<ThreadArgs*>(arg);
int argc = args->argc;
char **argv = args->argv;
@@ -562,16 +738,17 @@ void* cloudfrontthread(void* arg) {
std::cerr << "[cloudfrontthread] Failed to parse index from argv[0]: " << argv[0] << "\n";
return nullptr;
}
}
}*/
(void)arg;
const int index = 0;
// 更新线程状态为运行中
pthread_mutex_lock(&thread_info[index].lock);
printf("cloudfrontthread %d started\n", index);
safe_out_line(std::string("cloudfrontthread") + std::to_string(index) + " started\n");
thread_info[index].state = THREAD_RUNNING;
pthread_mutex_unlock(&thread_info[index].lock);
///////////////////////////////////////
// 解析命令行参数
/*// 解析命令行参数
if(!parse_param(argc,argv)){
std::cerr << "process param error,exit" << std::endl;
cleanup_args(args);
@@ -579,24 +756,24 @@ void* cloudfrontthread(void* arg) {
}
// 线程使用完后清理参数
cleanup_args(args);
cleanup_args(args);*/
//路径获取
FRONT_PATH = get_parent_directory();
std::cout << "FRONT_PATH:" << FRONT_PATH << std::endl;
safe_out_line("FRONT_PATH:" + FRONT_PATH + "\n");
//声明前置
std::unique_ptr<Front> FrontProcess;
FrontProcess = make_unique<Front>();
std::cout << "[Main] Program running in background.\n";
safe_out_line("[Main] Program running in background.\n");
// 5) 主线程保持后台运行
while(running) {
{
std::lock_guard<std::mutex> lock(FrontProcess->m_threadCheckMutex);
if (FrontProcess->m_needRestartFrontThread) {
/*if (FrontProcess->m_needRestartFrontThread) {
std::cout << "[Monitor] Restarting FrontThread..." << std::endl;
FrontProcess->StartFrontThread();
FrontProcess->m_needRestartFrontThread = false;
@@ -618,12 +795,46 @@ void* cloudfrontthread(void* arg) {
std::cout << "[Monitor] Restarting TimerThread..." << std::endl;
FrontProcess->StartTimerThread();
FrontProcess->m_needRestartTimerThread = false;
}*/
if (FrontProcess->m_needRestartFrontThread) {
safe_out_line("[Monitor] Restarting FrontThread...\n");
FrontProcess->StopFrontThread();
FrontProcess->StartFrontThread();
FrontProcess->m_needRestartFrontThread = false;
}
if (FrontProcess->m_needRestartConsumerThread) {
safe_out_line("[Monitor] Restarting MQConsumerThread...\n");
FrontProcess->StopMQConsumerThread();
FrontProcess->StartMQConsumerThread();
FrontProcess->m_needRestartConsumerThread = false;
}
if (FrontProcess->m_needRestartProducerThread) {
safe_out_line("[Monitor] Restarting MQProducerThread...\n");
FrontProcess->StopMQProducerThread();
FrontProcess->StartMQProducerThread();
FrontProcess->m_needRestartProducerThread = false;
}
if (FrontProcess->m_needRestartTimerThread) {
safe_out_line("[Monitor] Restarting TimerThread...\n");
FrontProcess->StopTimerThread(); // 先停
FrontProcess->StartTimerThread(); // 再启
FrontProcess->m_needRestartTimerThread = false;
}
}
std::this_thread::sleep_for(std::chrono::seconds(60));//每分钟检测一次
}
// 退出前标记为 STOPPED方便监控线程判断并重启
pthread_mutex_lock(&thread_info[index].lock);
thread_info[index].state = THREAD_STOPPED;
safe_out_line(std::string("cloudfrontthread ") + std::to_string(index) + " stopped\n");
pthread_mutex_unlock(&thread_info[index].lock);
return nullptr;
}

File diff suppressed because it is too large Load Diff

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);
@@ -347,6 +352,8 @@ void rocketmq_test_rt(Front* front);
void rocketmq_test_getdir(Front* front);
void InitializeProducer(rocketmq::RocketMQProducer*& producer);
void rocketmq_test_ud_batch(Front* front, int processNo, int start, int count);
#endif // _ROCKETMQ_CLIENT_WRAPPER_H_

View File

@@ -49,12 +49,13 @@ extern std::list<std::string> errorList, warnList, normalList;
extern std::mutex errorListMutex, warnListMutex, normalListMutex;
extern int IED_COUNT;
extern int INITFLAG;
extern std::atomic<int> INITFLAG;
extern int g_front_seg_index;
extern std::string subdir;
extern int G_TEST_NUM;
extern int G_TEST_TYPE;
extern int LEDGER_MAX_ITEMS;
extern bool errorOutputEnabled;
extern bool warnOutputEnabled;
@@ -259,6 +260,11 @@ extern bool normalOutputEnabled;
G_TEST_TYPE = type;
}
void Worker::setMaxItems(int items) {
std::lock_guard<std::mutex> locker(testMutex);
LEDGER_MAX_ITEMS = items;
}
// 日志控制
void Worker::setTestlog(bool flag) {
redirectErrorOutput(flag);
@@ -293,7 +299,10 @@ extern bool normalOutputEnabled;
"Available commands:\r\n"
"G_TEST_NUM=<num> - Set the G_TEST_NUM\r\n"
"G_TEST_TYPE=<num> - Set the G_TEST_TYPE 0:use ledger,1:use number\r\n"
"TESTLEDGER <processNo>,<start>,<count> - Batch send UD ledger updates (e.g. TESTLEDGER 3,1,50)\r\n"
"LOG=<bool> - Set the LOG\r\n"
"LOGLIST - List all registered loggers\r\n"
"MAX=<int> - Set the MAX_ITEMS\r\n"
"dir - Execute rocketmq_test_getdir\r\n"
"rc - Execute rocketmq_test_rc\r\n"
"rt - Execute rocketmq_test_rt\r\n"
@@ -308,22 +317,98 @@ extern bool normalOutputEnabled;
"exit - Exit the shell\r\n"
"help - Show this help message\r\n";
sendStr(clientFD, "\r\x1B[K" + helpText);
} else if (cmd.find("TESTLEDGER") == 0) {
// 支持TESTLEDGER 3,1,50中间允许空格
size_t pos = cmd.find(' ');
if (pos == std::string::npos || pos + 1 >= cmd.size()) {
sendStr(clientFD, "\r\x1B[KUsage: TESTLEDGER <processNo>,<start>,<count>\r\n");
} else {
std::string args = cmd.substr(pos + 1);
// 去掉可能的空格
for (size_t i = 0; i < args.size(); ) {
if (args[i] == ' ' || args[i] == '\t' || args[i] == '\r' || args[i] == '\n')
args.erase(i, 1);
else
++i;
}
// 解析三个整数
int processNo = 0, start = 0, count = 0;
size_t c1 = args.find(',');
size_t c2 = (c1 == std::string::npos) ? std::string::npos : args.find(',', c1 + 1);
if (c1 == std::string::npos || c2 == std::string::npos) {
sendStr(clientFD, "\r\x1B[KUsage: TESTLEDGER <processNo>,<start>,<count> (e.g. TESTLEDGER 3,1,50)\r\n");
} else {
processNo = std::atoi(args.substr(0, c1).c_str());
start = std::atoi(args.substr(c1 + 1, c2 - (c1 + 1)).c_str());
count = std::atoi(args.substr(c2 + 1).c_str());
if (processNo <= 0 || start <= 0 || count <= 0) {
sendStr(clientFD, "\r\x1B[KInvalid args. Need >0. Example: TESTLEDGER 3,1,50\r\n");
} else {
// 调用批量发送每条间隔1秒的逻辑在函数内部
rocketmq_test_ud_batch(m_front, processNo, start, count);
sendStr(clientFD, "\r\x1B[KExecuted TESTLEDGER batch send\r\n");
}
}
}
} else if (cmd.find("viewlog") == 0) {
showinshellflag = true;
handleViewLogCommand(cmd, clientFD);
} else if (cmd.find("G_TEST_NUM=") == 0) {
int num = std::atoi(cmd.substr(9).c_str());
int num = std::atoi(cmd.substr(11).c_str());
setTestNum(num);
sendStr(clientFD, "\r\x1B[KTEST_NUM updated\r\n");
} else if (cmd.find("G_TEST_TYPE=") == 0) {
int type = std::atoi(cmd.substr(10).c_str());
int type = std::atoi(cmd.substr(12).c_str());
setTestType(type);
sendStr(clientFD, "\r\x1B[KTEST_TYPE updated\r\n");
} else if (cmd.find("LOG=") == 0) {
int flag = std::atoi(cmd.substr(4).c_str());
setTestlog(flag);
sendStr(clientFD, "\r\x1B[KLOG updated\r\n");
} else if (cmd == "rc") {
}else if (cmd == "LOGLIST" || cmd == "loglist") {
std::ostringstream oss;
// 1⃣ 打印 logger_map
oss << "\r\x1B[KRegistered loggers (" << logger_map.size() << "):\r\n";
for (const auto& it : logger_map) {
oss << " " << it.first << "\r\n";
}
// 2⃣ 打印 LogLevelCache原子只读
std::shared_ptr<LogLevelCache> cache =
std::atomic_load_explicit(&g_level_cache_sp, std::memory_order_acquire);
if (!cache) {
oss << "\r\x1B[K[LogLevelCache] <EMPTY>\r\n";
} else {
oss << "\r\x1B[K[LogLevelCache] terminal levels ("
<< cache->term_min.size() << "):\r\n";
for (const auto& kv : cache->term_min) {
oss << " terminal." << kv.first
<< " -> " << loglevel_to_str(kv.second) << "\r\n";
}
oss << "\r\x1B[K[LogLevelCache] monitor levels ("
<< cache->mp_min.size() << "):\r\n";
for (const auto& kv : cache->mp_min) {
oss << " monitor." << kv.first
<< " -> " << loglevel_to_str(kv.second) << "\r\n";
}
}
sendStr(clientFD, oss.str());
}else if (cmd.find("MAX=") == 0) {
int flag = std::atoi(cmd.substr(4).c_str());
setMaxItems(flag);
sendStr(clientFD, "\r\x1B[KMAX_ITEMS updated\r\n");
}
else if (cmd == "rc") {
rocketmq_test_rc(m_front);
sendStr(clientFD, "\r\x1B[KExecuted rocketmq_test_rc\r\n");
} else if (cmd == "getdir") {
@@ -410,10 +495,16 @@ extern bool normalOutputEnabled;
void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
// —— 显示控制:最多打印的元素数量(防止过长)——
constexpr size_t MAX_ITEMS = 5; // 可按需调整或删除限制
const size_t MAX_ITEMS = static_cast<size_t>(LEDGER_MAX_ITEMS); // 非 constexpr
std::ostringstream os;
os << "\r\x1B[K------------------------------------\n";
os << "\r\x1B[K|-- guid : " << dev.guid << "\n";
os << "\r\x1B[K|-- busytype : " << dev.busytype << "\n";
os << "\r\x1B[K|-- isbusy : " << dev.isbusy << "\n";
os << "\r\x1B[K|-- busytimecount : " << dev.busytimecount << "\n";
//os << "\r\x1B[K|-- dev_index : " << dev.dev_index << "\n";
os << "\r\x1B[K|-- terminal_id : " << dev.terminal_id << "\n";
os << "\r\x1B[K|-- terminal_name : " << dev.terminal_name << "\n";
@@ -432,6 +523,7 @@ void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
os << "\r\x1B[K|-- timestamp : " << dev.timestamp << "\n";
os << "\r\x1B[K|-- Righttime : " << dev.Righttime << "\n";
os << "\r\x1B[K|-- mac : " << dev.mac << "\n";
os << "\r\x1B[K|-- loglevel : " << dev.DevLogLevel << "\n";
// ========================= 终端级 · 内部定值 =========================
// internal_valuesushort 列表)与 dz_internal_info_list 一一对应,仅展示前 MAX_ITEMS 条
@@ -497,6 +589,7 @@ void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
os << "\r\x1B[K |-- terminal_connect : " << ld.terminal_connect << "\n";
os << "\r\x1B[K |-- status : " << ld.status << "\n";
os << "\r\x1B[K |-- timestamp : " << ld.timestamp << "\n";
os << "\r\x1B[K |-- loglevel : " << ld.LineLogLevel << "\n";
os << "\r\x1B[K |-- CT1=" << ld.CT1 << ", CT2=" << ld.CT2
<< ", PT1=" << ld.PT1 << ", PT2=" << ld.PT2 << "\n";
@@ -602,6 +695,133 @@ void Worker::printLedgerinshell(const terminal_dev& dev, int fd) {
os << "\r\x1B[K |.. (+" << (n - MAX_ITEMS) << " more)\n";
}
}
// ========================= ★新增:补招打印 =========================
// ★新增:小工具—把状态/阶段枚举转成可读字符串
auto recallStatusStr = [](int st) -> const char* {
switch (st) {
case 0: return "NOT_STARTED(0)";
case 1: return "RUNNING(1)";
case 2: return "DONE(2)";
case 3: return "FAILED(3)";
case 4: return "EMPTY(4)";
default: return "UNKNOWN";
}
};
auto phaseStr = [](RecallPhase p) -> const char* {
switch (p) {
case RecallPhase::IDLE: return "IDLE";
case RecallPhase::LISTING: return "LISTING";
case RecallPhase::DOWNLOADING: return "DOWNLOADING";
}
return "UNKNOWN";
};
auto resultStr = [](ActionResult r) -> const char* {
switch (r) {
case ActionResult::PENDING: return "PENDING";
case ActionResult::FAIL: return "FAIL";
case ActionResult::OK: return "OK";
}
return "UNKNOWN";
};
// --- ★新增事件补招RecallMonitor ---
os << "\r\x1B[K |-- Recall(Event) (" << ld.recall_list.size() << "):\n";
{
size_t idx = 0;
for (const auto& r : ld.recall_list) {
if (idx++ >= MAX_ITEMS) break;
os << "\r\x1B[K |-- [" << (idx-1) << "] "
<< "status=" << recallStatusStr(r.recall_status)
<< ", StartTime=" << r.StartTime
<< ", EndTime=" << r.EndTime
<< ", STEADY=" << r.STEADY
<< ", VOLTAGE=" << r.VOLTAGE
<< "\n";
}
if (ld.recall_list.size() > MAX_ITEMS) {
os << "\r\x1B[K |.. (+" << (ld.recall_list.size() - MAX_ITEMS) << " more)\n";
}
}
// --- ★新增稳态补招RecallFile+ 状态机信息 ---
os << "\r\x1B[K |-- Recall(Static Files) (" << ld.recall_list_static.size() << "):\n";
{
size_t idx = 0;
for (const auto& rf : ld.recall_list_static) {
if (idx++ >= MAX_ITEMS) break;
os << "\r\x1B[K |-- [" << (idx-1) << "] "
<< "status=" << recallStatusStr(rf.recall_status)
<< ", StartTime=" << rf.StartTime
<< ", EndTime=" << rf.EndTime
<< ", STEADY=" << rf.STEADY
<< ", VOLTAGE=" << rf.VOLTAGE
<< "\n";
// ★新增:直下模式与目标时间列表
os << "\r\x1B[K |-- direct_mode=" << (rf.direct_mode ? "true" : "false")
<< ", target_filetimes(" << rf.target_filetimes << ")\n";
{
os << "\r\x1B[K |.. " << rf.target_filetimes << "\n";
}
// ★新增:状态机运行态
os << "\r\x1B[K |-- phase=" << phaseStr(rf.phase)
<< ", cur_dir_index=" << rf.cur_dir_index
<< ", cur_dir=" << rf.cur_dir << "\n";
os << "\r\x1B[K |-- list_result=" << resultStr(rf.list_result)
<< ", download_result=" << resultStr(rf.download_result) << "\n";
// ★新增:候选目录
os << "\r\x1B[K |-- dir_candidates(" << rf.dir_candidates.size() << ")\n";
{
size_t c = 0;
for (const auto& d : rf.dir_candidates) {
if (c++ >= MAX_ITEMS) break;
os << "\r\x1B[K |-- " << d << "\n";
}
if (rf.dir_candidates.size() > MAX_ITEMS) {
os << "\r\x1B[K |.. (+" << (rf.dir_candidates.size() - MAX_ITEMS) << " more)\n";
}
}
// ★新增:目录 -> 文件名列表(仅概要)
os << "\r\x1B[K |-- dir_files(" << rf.dir_files.size() << " dirs)\n";
{
size_t c = 0;
for (const auto& kv : rf.dir_files) {
if (c++ >= MAX_ITEMS) break;
os << "\r\x1B[K |-- [" << (c-1) << "] dir=" << kv.first
<< " files=" << kv.second.size() << "\n";
}
if (rf.dir_files.size() > MAX_ITEMS) {
os << "\r\x1B[K |.. (+" << (rf.dir_files.size() - MAX_ITEMS) << " more)\n";
}
}
// ★新增:下载队列(概要)
os << "\r\x1B[K |-- download_queue(" << rf.download_queue.size() << ")\n";
{
size_t c = 0;
for (const auto& path : rf.download_queue) {
if (c++ >= MAX_ITEMS) break;
os << "\r\x1B[K |-- " << path << "\n";
}
if (rf.download_queue.size() > MAX_ITEMS) {
os << "\r\x1B[K |.. (+" << (rf.download_queue.size() - MAX_ITEMS) << " more)\n";
}
}
// ★新增:当前下载中文件
if (!rf.downloading_file.empty()) {
os << "\r\x1B[K |-- downloading: " << rf.downloading_file << "\n";
}
}
if (ld.recall_list_static.size() > MAX_ITEMS) {
os << "\r\x1B[K |.. (+" << (ld.recall_list_static.size() - MAX_ITEMS) << " more)\n";
}
}
// ======================= ★新增:补招打印结束 =======================
}
os << "\r\x1B[K------------------------------------\n";

View File

@@ -59,6 +59,7 @@ private:
void sendBytes(int fd, const char* buf, int len);
void setTestNum(int num);
void setTestType(int type);
void setMaxItems(int items);
void setTestlog(bool flag);
void doPeriodicTask();
void processCommand(const std::string &cmd, int clientFD);

File diff suppressed because it is too large Load Diff

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>
@@ -34,8 +35,8 @@ typedef struct {
} thread_info_t;
#endif
extern int INITFLAG;//̨<>˵ȳ<CBB5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD>־
extern void cleanup_args(ThreadArgs* args);
extern std::atomic<int> INITFLAG;//̨<>˵ȳ<CBB5>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD>ɱ<EFBFBD>־
//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;
@@ -154,29 +111,22 @@ void* client_manager_thread(void* arg) {
printf("Started client connections\n");
// <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>100<30><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD>װ<EFBFBD><D7B0>
//std::vector<DeviceInfo> test_devices = generate_test_devices(100);
//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
// }
//};
//lnk<6E><6B>̨<EFBFBD>˶<EFBFBD>ȡ<EFBFBD>
std::vector<DeviceInfo> devices = GenerateDeviceInfoFromLedger(terminal_devlist);//lnk<6E><6B><EFBFBD><EFBFBD>
@@ -196,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;
@@ -234,58 +184,139 @@ 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) {
//lnk20251208
pthread_t old_tid = 0;
pthread_mutex_lock(&global_lock);
if (thread_info[index].state == THREAD_RESTARTING) {
pthread_mutex_unlock(&global_lock);
return; // <20><><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>
}
// <20><><EFBFBD><EFBFBD>֮ǰ<D6AE><C7B0> STOPPED<45><44><EFBFBD><EFBFBD><EFBFBD><EFBFBD> tid <20>ǿգ<C7BF><D5A3><EFBFBD><EFBFBD>Ի<EFBFBD><D4BB><EFBFBD>һ<EFBFBD>¾<EFBFBD><C2BE>̣߳<DFB3><CCA3><EFBFBD>ֹ<EFBFBD><D6B9>Դй¶<D0B9><C2B6>lnk20251208
if (thread_info[index].state == THREAD_STOPPED && thread_info[index].tid) {
old_tid = thread_info[index].tid;
thread_info[index].tid = 0;
}
thread_info[index].state = THREAD_RESTARTING;
printf("Restarting thread %d\n", index);
pthread_mutex_unlock(&global_lock);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
int* new_index = (int*)malloc(sizeof(int));
*new_index = index;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> join<69><6E><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD>
if (old_tid) {
pthread_join(old_tid, NULL);
}
if (index == 1) {
// ========== <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD> ==========lnk20251208
if (index == 0) {
// <20>ӿ<EFBFBD> + MQ<4D><51>cloudfrontthread <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>Ӵ<EFBFBD> NULL
if (pthread_create(&thread_info[index].tid, NULL,
cloudfrontthread, NULL) != 0) {
pthread_mutex_lock(&global_lock);
printf("Failed to restart cloudfrontthread %d\n", index);
thread_info[index].state = THREAD_CRASHED;
pthread_mutex_unlock(&global_lock);
}
} else if (index == 1 && !PQD_FLAG) {
// <20>ͻ<EFBFBD><CDBB>˹<EFBFBD><CBB9><EFBFBD><EFBFBD>߳<EFBFBD>
if (pthread_create(&thread_info[index].tid, NULL, client_manager_thread, new_index) != 0) {
int* new_index = (int*)malloc(sizeof(int));
if (!new_index) {
pthread_mutex_lock(&global_lock);
printf("Failed to malloc for client manager 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,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);
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>
if (pthread_create(&thread_info[index].tid, NULL, message_processor_thread, new_index) != 0) {
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,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, args) != 0) {
} 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);
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>
} else {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߳<EFBFBD><EFBFBD>ݲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
}
}
@@ -294,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)){
@@ -321,10 +342,10 @@ int main(int argc ,char** argv) {//
}
//<2F>ӿں<D3BF>mq
ThreadArgs* args = make_thread_args_from_strs({ "0" });
if (pthread_create(&thread_info[0].tid, NULL, cloudfrontthread, args) != 0) {
//ThreadArgs* args = make_thread_args_from_strs({ "0" });
if (pthread_create(&thread_info[0].tid, NULL, cloudfrontthread, NULL) != 0) {
printf("Failed to create message processor thread 0\n");
cleanup_args(args);
//cleanup_args(args);
}
while(!INITFLAG){
@@ -337,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>
@@ -395,36 +413,13 @@ 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>socket<65><74><EFBFBD><EFBFBD>״̬
static int queue_monitor = 0;
//static int count = 3;
if (++queue_monitor >= 20) { // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>
static bool flag = false;
if (++queue_monitor >= 60) {
printf("Message queue size: %zu\n", message_queue.size());
queue_monitor = 0;
/*for (const auto& device : devices) {
//ClientManager::instance().add_device(device);
}*/
/*std::vector<DeviceInfo> test_devices = generate_test_devices(count);
count++;
for (const auto& device : test_devices) {
ClientManager::instance().remove_device("D001");
}*/
}
}

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();

Binary file not shown.

BIN
稳定性问题调查.docx Normal file

Binary file not shown.