KiCad PCB EDA Suite
Loading...
Searching...
No Matches
vrml_line_reader.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or (at your option)
9 * any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-3.0.html
19 */
20
21#include "vrml_line_reader.h"
22
24
25#include <wx/wxcrt.h>
26
27#include <algorithm>
28#include <cstdio>
29#include <cstring>
30#include <stdexcept>
31
32
33VRML_LINE_READER::VRML_LINE_READER( const wxString& aFileName, unsigned aStartingLineNumber, unsigned aMaxLineLength,
34 const S3D::MODEL_IMPORT_OPTIONS& aOptions ) :
35 m_file( wxFopen( aFileName, wxS( "rb" ) ) ),
36 m_source( aFileName ),
37 m_buffer( 64 * 1024 ),
38 m_lineNumber( aStartingLineNumber ),
39 m_maxLineLength( aMaxLineLength ),
40 m_options( aOptions )
41{
42 if( !m_file )
43 throw std::runtime_error( "Unable to open model file" );
44
45 m_line.reserve( std::min( aMaxLineLength, 4096U ) + 1U );
46}
47
48
50{
51 std::fclose( m_file );
52}
53
54
56{
57 m_bufferPos = 0;
58 m_bufferEnd = std::fread( m_buffer.data(), 1, m_buffer.size(), m_file );
59
60 if( m_bufferEnd == 0 && std::ferror( m_file ) )
61 throw std::runtime_error( "Unable to read model file" );
62
63 return m_bufferEnd != 0;
64}
65
66
68{
69 if( m_options.IsCanceled() )
71
72 m_line.clear();
73
74 for( ;; )
75 {
76 if( m_bufferPos == m_bufferEnd && !fill() )
77 break;
78
79 const char* start = m_buffer.data() + m_bufferPos;
80 const char* found = static_cast<const char*>( std::memchr( start, '\n', m_bufferEnd - m_bufferPos ) );
81 const std::size_t span = found ? static_cast<std::size_t>( found - start ) + 1U : m_bufferEnd - m_bufferPos;
82
83 if( m_line.size() + span > m_maxLineLength )
84 throw std::runtime_error( "Maximum model line length exceeded" );
85
86 m_line.append( start, span );
87 m_bufferPos += span;
88
89 if( found )
90 break;
91 }
92
94
95 if( m_line.empty() )
96 return nullptr;
97
98 m_line.push_back( '\0' );
99 return m_line.data();
100}
std::size_t m_bufferEnd
std::vector< char > m_buffer
std::size_t m_bufferPos
S3D::MODEL_IMPORT_OPTIONS m_options
bool fill()
Refill the read buffer, returning false at end of file or on a read error.
VRML_LINE_READER(const wxString &aFileName, unsigned aStartingLineNumber, unsigned aMaxLineLength, const S3D::MODEL_IMPORT_OPTIONS &aOptions)