@@ -42,7 +42,60 @@ NMR_OpcPackageReader.cpp defines an OPC Package reader in a portable way.
42
42
#include < iostream>
43
43
44
44
namespace NMR {
45
+
46
+ // custom callbck function for reading from a CImportStream on the fly
47
+ zip_int64_t custom_zip_source_callback (void *userData, void *data, zip_uint64_t len, zip_source_cmd_t cmd) {
48
+ if (userData == nullptr )
49
+ throw CNMRException (NMR_ERROR_INVALIDPARAM);
50
+
51
+ CImportStream* pImportStream = (CImportStream*)(userData);
52
+
53
+ switch (cmd) {
54
+ case ZIP_SOURCE_SUPPORTS:
55
+ zip_int64_t bitmap;
56
+ bitmap = zip_source_make_command_bitmap (ZIP_SOURCE_OPEN, ZIP_SOURCE_READ, ZIP_SOURCE_CLOSE,
57
+ ZIP_SOURCE_STAT, ZIP_SOURCE_ERROR, ZIP_SOURCE_SEEK, ZIP_SOURCE_TELL, ZIP_SOURCE_SUPPORTS, -1 );
58
+ return bitmap;
59
+
60
+ case ZIP_SOURCE_SEEK:
61
+ zip_source_args_seek argsSeek;
62
+ argsSeek = * ((zip_source_args_seek *)data);
63
+ if (argsSeek.whence == SEEK_SET)
64
+ pImportStream->seekPosition (argsSeek.offset , true );
65
+ else if (argsSeek.whence == SEEK_CUR)
66
+ pImportStream->seekForward (argsSeek.offset , true );
67
+ else if (argsSeek.whence == SEEK_END) {
68
+ pImportStream->seekFromEnd (argsSeek.offset , true );
69
+ }
70
+ else
71
+ throw CNMRException (0 );
72
+ return 0 ;
73
+
74
+ case ZIP_SOURCE_OPEN:
75
+ return 0 ;
76
+
77
+ case ZIP_SOURCE_READ:
78
+ return pImportStream->readBuffer ((nfByte*)data, len, true );
79
+
80
+ case ZIP_SOURCE_CLOSE:
81
+ return 0 ;
82
+
83
+ case ZIP_SOURCE_TELL:
84
+ return pImportStream->getPosition ();
45
85
86
+ case ZIP_SOURCE_STAT:
87
+ zip_stat_t * zipStat;
88
+ zipStat = (zip_stat_t *)data;
89
+ zip_stat_init (zipStat);
90
+ zipStat->size = pImportStream->retrieveSize ();
91
+ zipStat->valid |= ZIP_STAT_SIZE;
92
+ return sizeof (zip_stat_t );
93
+
94
+ default :
95
+ throw CNMRException (NMR_ERROR_ZIPCALLBACK);
96
+ }
97
+ return -1 ;
98
+ }
46
99
47
100
COpcPackageReader::COpcPackageReader (_In_ PImportStream pImportStream, _In_ PModelReaderWarnings pWarnings)
48
101
{
@@ -65,13 +118,19 @@ namespace NMR {
65
118
if (nStreamSize == 0 )
66
119
throw CNMRException (NMR_ERROR_COULDNOTGETSTREAMPOSITION);
67
120
68
- // read ZIP into memory
69
- m_Buffer.resize ((size_t ) nStreamSize);
70
- pImportStream->readBuffer (&m_Buffer[0 ], nStreamSize, true );
71
-
72
121
// create ZIP objects
73
122
zip_error_init (&m_ZIPError);
74
- m_ZIPsource = zip_source_buffer_create (&m_Buffer[0 ], (size_t ) nStreamSize, 0 , &m_ZIPError);
123
+
124
+ if (true ) {
125
+ // read ZIP from callback: faster and requires less memory
126
+ m_ZIPsource = zip_source_function_create (custom_zip_source_callback, pImportStream.get (), &m_ZIPError);
127
+ }
128
+ else {
129
+ // read ZIP into memory
130
+ m_Buffer.resize ((size_t )nStreamSize);
131
+ pImportStream->readBuffer (&m_Buffer[0 ], nStreamSize, true );
132
+ m_ZIPsource = zip_source_buffer_create (&m_Buffer[0 ], (size_t )nStreamSize, 0 , &m_ZIPError);
133
+ }
75
134
if (m_ZIPsource == nullptr )
76
135
throw CNMRException (NMR_ERROR_COULDNOTREADZIPFILE);
77
136
0 commit comments