54 FILE* fp = wxFopen( aFilePath,
"rb" );
58 THROW_IO_ERROR( wxString::Format(
_(
"Cannot open file '%s'." ), aFilePath ) );
61 fseek( fp, 0, SEEK_END );
62 long len = ftell( fp );
73 fseek( fp, 0, SEEK_SET );
75 size_t bytesRead = fread(
m_buffer.data(),
sizeof(
unsigned char ), len, fp );
78 if(
static_cast<size_t>( len ) != bytesRead )
87 catch( CFB::CFBException& exception )
119 wxCHECK( aOutput,
false );
120 wxCHECK( cfe.size >= 1,
false );
122 size_t streamSize = cfe.size;
123 wxMemoryBuffer buffer( streamSize );
124 buffer.SetDataLen( streamSize );
131 if( buffer[0] == 0x02 )
133 wxMemoryInputStream memoryInputStream( buffer.GetData(), streamSize );
134 memoryInputStream.SeekI( 1, wxFromStart );
136 wxZlibInputStream zlibInputStream( memoryInputStream );
137 wxMemoryOutputStream decodedPcbLibStream;
138 decodedPcbLibStream << zlibInputStream;
140 wxStreamBuffer* outStream = decodedPcbLibStream.GetOutputStreamBuffer();
141 aOutput->
InitFromBuffer( outStream->GetBufferStart(), outStream->GetIntPosition() );
144 else if( buffer[0] == 0x00 )
146 aOutput->
InitFromBuffer(
static_cast<uint8_t*
>( buffer.GetData() ) + 1, streamSize - 1 );
151 wxFAIL_MSG( wxString::Format(
"Altium IntLib unknown header: %02x %02x %02x %02x %02x",
152 buffer[0], buffer[1], buffer[2], buffer[3], buffer[4] ) );
161 const std::string aName,
const bool aIsStream )
const
166 const CFB::COMPOUND_FILE_ENTRY* ret =
nullptr;
169 [&](
const CFB::COMPOUND_FILE_ENTRY* entry,
const CFB::utf16string& dir,
175 if(
m_reader->IsStream( entry ) == aIsStream )
177 std::string
name = UTF16ToUTF8( entry->name );
178 if(
name == aName.c_str() )
194 const CFB::COMPOUND_FILE_ENTRY* root = aStart ? aStart :
m_reader->GetRootEntry();
199 std::map<wxString, ALTIUM_SYMBOL_DATA> folders;
201 m_reader->EnumFiles( root, 1, [&](
const CFB::COMPOUND_FILE_ENTRY* tentry,
202 const CFB::utf16string&,
int ) ->
int
204 wxString dirName = UTF16ToWstring( tentry->name, tentry->nameLen );
210 [&](
const CFB::COMPOUND_FILE_ENTRY* entry,
211 const CFB::utf16string&,
int ) ->
int
213 std::wstring fileName = UTF16ToWstring( entry->name, entry->nameLen );
215 if(
m_reader->IsStream( entry ) && fileName ==
L"Data" )
216 folders[dirName].m_symbol = entry;
218 if(
m_reader->IsStream( entry ) && fileName ==
L"PinFrac" )
219 folders[dirName].m_pinsFrac = entry;
221 if(
m_reader->IsStream( entry ) && fileName ==
L"PinWideText" )
222 folders[dirName].m_pinsWideText = entry;
224 if(
m_reader->IsStream( entry ) && fileName ==
L"PinTextData" )
225 folders[dirName].m_pinsTextData = entry;
240 const CFB::COMPOUND_FILE_ENTRY* root =
m_reader->GetRootEntry();
245 std::map<wxString, const CFB::COMPOUND_FILE_ENTRY*> files;
249 [&](
const CFB::COMPOUND_FILE_ENTRY* tentry,
const CFB::utf16string& dir,
255 std::wstring dirName = UTF16ToWstring( tentry->name, tentry->nameLen );
257 if( dirName != aDir )
262 [&](
const CFB::COMPOUND_FILE_ENTRY* entry,
const CFB::utf16string&,
267 std::wstring fileName =
268 UTF16ToWstring( entry->name, entry->nameLen );
270 files[fileName] = entry;
284 const std::vector<std::string>& aStreamPath )
const
292 auto it = aStreamPath.cbegin();
294 while( aStart !=
nullptr )
296 const std::string&
name = *it;
298 if( ++it == aStreamPath.cend() )
346 std::function<std::map<wxString, wxString>(
const std::string& )> handleBinaryData )
349 static wxCSConv convISO8859_1 = wxConvISO8859_1;
351 std::map<wxString, wxString>
kv;
354 bool isBinary = ( length & 0xff000000 ) != 0;
356 length &= 0x00ffffff;
371 bool hasNullByte =
m_pos[length - 1] ==
'\0';
373 if( !hasNullByte && !isBinary )
375 wxLogTrace(
"ALTIUM", wxT(
"Missing null byte at end of property list. Imported data "
376 "might be malformed or missing." ) );
381 std::string str = std::string(
m_pos, length - ( ( hasNullByte && !isBinary ) ? 1 : 0 ) );
386 return handleBinaryData( str );
389 std::size_t token_end = 0;
391 while( token_end < str.size() && token_end != std::string::npos )
393 std::size_t token_start = str.find(
'|', token_end );
394 std::size_t token_equal = str.find(
'=', token_end );
395 std::size_t key_start;
397 if( token_start <= token_equal )
399 key_start = token_start + 1;
404 key_start = token_end;
407 token_end = str.find(
'|', key_start );
409 if( token_equal >= token_end )
414 if( token_end == std::string::npos )
416 token_end = str.size() + 1;
419 std::string keyS = str.substr( key_start, token_equal - key_start );
420 std::string valueS = str.substr( token_equal + 1, token_end - token_equal - 1 );
424 wxString key( keyS.c_str(), convISO8859_1 );
427 wxString canonicalKey = key.Trim(
false ).Trim(
true ).MakeUpper();
432 if( canonicalKey.StartsWith(
"%UTF8%" ) )
433 value = wxString( valueS.c_str(), wxConvUTF8 );
435 value = wxString( valueS.c_str(), convISO8859_1 );
437 if( canonicalKey != wxS(
"PATTERN" ) && canonicalKey != wxS(
"SOURCEFOOTPRINTLIBRARY" ) )
441 value.Replace( wxT(
"ÿ" ), wxT(
" " ) );
444 if( canonicalKey == wxT(
"DESIGNATOR" )
445 || canonicalKey == wxT(
"NAME" )
446 || canonicalKey == wxT(
"TEXT" ) )
448 if(
kv[ wxT(
"RECORD" ) ] != wxT(
"4" ) )
452 kv.insert( { canonicalKey, value.Trim() } );