54 FILE* fp = wxFopen( aFilePath,
"rb" );
59 fseek( fp, 0, SEEK_END );
60 long len = ftell( fp );
71 fseek( fp, 0, SEEK_SET );
73 size_t bytesRead = fread(
m_buffer.data(),
sizeof(
unsigned char ), len, fp );
76 if(
static_cast<size_t>( len ) != bytesRead )
85 catch( CFB::CFBException& exception )
117 wxCHECK( aOutput,
false );
118 wxCHECK( cfe.size >= 1,
false );
120 size_t streamSize = cfe.size;
121 wxMemoryBuffer buffer( streamSize );
122 buffer.SetDataLen( streamSize );
129 if( buffer[0] == 0x02 )
131 wxMemoryInputStream memoryInputStream( buffer.GetData(), streamSize );
132 memoryInputStream.SeekI( 1, wxFromStart );
134 wxZlibInputStream zlibInputStream( memoryInputStream );
135 wxMemoryOutputStream decodedPcbLibStream;
136 decodedPcbLibStream << zlibInputStream;
138 wxStreamBuffer* outStream = decodedPcbLibStream.GetOutputStreamBuffer();
139 aOutput->
InitFromBuffer( outStream->GetBufferStart(), outStream->GetIntPosition() );
142 else if( buffer[0] == 0x00 )
144 aOutput->
InitFromBuffer(
static_cast<uint8_t*
>( buffer.GetData() ) + 1, streamSize - 1 );
149 wxFAIL_MSG( wxString::Format(
"Altium IntLib unknown header: %02x %02x %02x %02x %02x",
150 buffer[0], buffer[1], buffer[2], buffer[3], buffer[4] ) );
159 const std::string aName,
const bool aIsStream )
const
164 const CFB::COMPOUND_FILE_ENTRY* ret =
nullptr;
167 [&](
const CFB::COMPOUND_FILE_ENTRY* entry,
const CFB::utf16string& dir,
173 if(
m_reader->IsStream( entry ) == aIsStream )
175 std::string
name = UTF16ToUTF8( entry->name );
176 if(
name == aName.c_str() )
192 const CFB::COMPOUND_FILE_ENTRY* root = aStart ? aStart :
m_reader->GetRootEntry();
197 std::map<wxString, ALTIUM_SYMBOL_DATA> folders;
199 m_reader->EnumFiles( root, 1, [&](
const CFB::COMPOUND_FILE_ENTRY* tentry,
200 const CFB::utf16string&,
int ) ->
int
202 wxString dirName = UTF16ToWstring( tentry->name, tentry->nameLen );
208 [&](
const CFB::COMPOUND_FILE_ENTRY* entry,
209 const CFB::utf16string&,
int ) ->
int
211 std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
213 if(
m_reader->IsStream( entry ) && fileName ==
L"Data" )
214 folders[dirName].m_symbol = entry;
216 if(
m_reader->IsStream( entry ) && fileName ==
L"PinFrac" )
217 folders[dirName].m_pinsFrac = entry;
219 if(
m_reader->IsStream( entry ) && fileName ==
L"PinWideText" )
220 folders[dirName].m_pinsWideText = entry;
222 if(
m_reader->IsStream( entry ) && fileName ==
L"PinTextData" )
223 folders[dirName].m_pinsTextData = entry;
238 const CFB::COMPOUND_FILE_ENTRY* root =
m_reader->GetRootEntry();
243 std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> files;
247 [&](
const CFB::COMPOUND_FILE_ENTRY* tentry,
const CFB::utf16string& dir,
253 std::wstring dirName = UTF16ToWstring( tentry->name, tentry->nameLen );
255 if( dirName != aDir )
260 [&](
const CFB::COMPOUND_FILE_ENTRY* entry,
const CFB::utf16string&,
265 std::wstring fileName =
266 UTF16ToWstring( entry->name, entry->nameLen );
268 files[fileName] = entry;
282 const std::vector<std::string>& aStreamPath )
const
290 auto it = aStreamPath.cbegin();
292 while( aStart !=
nullptr )
294 const std::string&
name = *it;
296 if( ++it == aStreamPath.cend() )
344 std::function<std::map<wxString, wxString>(
const std::string& )> handleBinaryData )
347 static wxCSConv convISO8859_1 = wxConvISO8859_1;
349 std::map<wxString, wxString>
kv;
352 bool isBinary = ( length & 0xff000000 ) != 0;
354 length &= 0x00ffffff;
369 bool hasNullByte =
m_pos[length - 1] ==
'\0';
371 if( !hasNullByte && !isBinary )
373 wxLogTrace(
"ALTIUM", wxT(
"Missing null byte at end of property list. Imported data "
374 "might be malformed or missing." ) );
379 std::string str = std::string(
m_pos, length - ( ( hasNullByte && !isBinary ) ? 1 : 0 ) );
384 return handleBinaryData( str );
387 std::size_t token_end = 0;
389 while( token_end < str.size() && token_end != std::string::npos )
391 std::size_t token_start = str.find(
'|', token_end );
392 std::size_t token_equal = str.find(
'=', token_end );
393 std::size_t key_start;
395 if( token_start <= token_equal )
397 key_start = token_start + 1;
402 key_start = token_end;
405 token_end = str.find(
'|', key_start );
407 if( token_equal >= token_end )
412 if( token_end == std::string::npos )
414 token_end = str.size() + 1;
417 std::string keyS = str.substr( key_start, token_equal - key_start );
418 std::string valueS = str.substr( token_equal + 1, token_end - token_equal - 1 );
422 wxString key( keyS.c_str(), convISO8859_1 );
425 wxString canonicalKey = key.Trim(
false ).Trim(
true ).MakeUpper();
430 if( canonicalKey.StartsWith(
"%UTF8%" ) )
431 value = wxString( valueS.c_str(), wxConvUTF8 );
433 value = wxString( valueS.c_str(), convISO8859_1 );
435 if( canonicalKey != wxS(
"PATTERN" ) && canonicalKey != wxS(
"SOURCEFOOTPRINTLIBRARY" ) )
439 value.Replace( wxT(
"ÿ" ), wxT(
" " ) );
442 kv.insert( { canonicalKey, value.Trim() } );
449 auto recordIt =
kv.find( wxT(
"RECORD" ) );
451 if( recordIt ==
kv.end() || recordIt->second != wxT(
"4" ) )
453 for(
const wxString& key : { wxT(
"DESIGNATOR" ), wxT(
"NAME" ), wxT(
"TEXT" ) } )
455 auto valueIt =
kv.find( key );
457 if( valueIt !=
kv.end() )