/////////////////////////////////////////////////////////////////////////////// // // The contents of this file are subject to the Mozilla Public License // Version 1.1 (the "License"); you may not use this file except in // compliance with the License. You may obtain a copy of the License at // http://www.mozilla.org/MPL/ // // Software distributed under the License is distributed on an "AS IS" // basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the // License for the specific language governing rights and limitations // under the License. // // The Original Code is MP4v2. // // The Initial Developer of the Original Code is Kona Blend. // Portions created by Kona Blend are Copyright (C) 2008. // All Rights Reserved. // // Contributors: // Kona Blend, kona8lend@@gmail.com // /////////////////////////////////////////////////////////////////////////////// #include "libutil/impl.h" namespace mp4v2 { namespace util { /////////////////////////////////////////////////////////////////////////////// Database::Database( const string& filename, const string& key ) : _filename ( filename ) , _key ( key ) { } /////////////////////////////////////////////////////////////////////////////// Database::~Database() { } /////////////////////////////////////////////////////////////////////////////// void Database::close() { _stream.close(); _stream.clear(); } /////////////////////////////////////////////////////////////////////////////// bool Database::open( bool write, string& fname ) { _currentKeyValue.clear(); _stream.clear(); _stream.open( fname.c_str(), write ? ios::out : ios::in ); return _stream.rdstate(); } /////////////////////////////////////////////////////////////////////////////// void Database::parseData( map& data ) { data.clear(); string name; string value; if ( _currentKeyValue.length() ) { data[ _key ] = _currentKeyValue; _currentKeyValue.clear(); } while ( !parsePair( name, value ) ) { if ( name == _key ) { _currentKeyValue = value; break; } data[ name ] = value; } } /////////////////////////////////////////////////////////////////////////////// bool Database::parsePair( string& name, string& value ) { enum Mode { LTRIM, COMMENT, NAME, DELIM, VALUE }; Mode mode = LTRIM; bool delimVisible = false; int visibleLength = 0; for ( char c; !_stream.get( c ).rdstate(); ) { switch( mode ) { case LTRIM: switch( c ) { case '\0': // NULL case '\t': // TAB case ' ': // SPACE case '\n': // NEWLINE case '\r': // CARRIAGE-RETURN break; case '#': // COMMENT mode = COMMENT; break; default: mode = NAME; name = tolower( c ); break; } break; case COMMENT: switch( c ) { case '\n': // NEWLINE case '\r': // CARRIAGE-RETURN mode = LTRIM; name.clear(); break; default: break; } break; case NAME: switch( c ) { case '\0': // NULL break; case '\n': // NEWLINE case '\r': // CARRIAGE-RETURN mode = LTRIM; break; case '\t': // TAB case ' ': // SPACE case '=': // DELIMITER mode = DELIM; delimVisible = false; break; default: name += tolower( c ); break; } break; case DELIM: switch( c ) { case '\n': // NEWLINE case '\r': // CARRIAGE-RETURN mode = LTRIM; name.clear(); break; case '\0': // NULL case '\t': // TAB case ' ': // SPACE break; case '=': // DELIMITER if( delimVisible ) { mode = VALUE; value = c; visibleLength = (uint32_t)value.length(); } delimVisible = true; break; default: mode = VALUE; value = c; visibleLength = (uint32_t)value.length(); break; } break; case VALUE: switch (c) { case '\0': // NULL break; case '\n': // NEWLINE case '\r': // CARRIAGE-RETURN if( visibleLength ) value.resize( visibleLength ); return false; case '\t': // TAB case ' ': // SPACE value += ' '; break; default: value += c; visibleLength = (uint32_t)value.length(); break; } break; default: break; } } if( mode != VALUE ) return true; if( visibleLength ) value.resize( visibleLength ); return false; } /////////////////////////////////////////////////////////////////////////////// }} // namespace mp4v2::util