| /////////////////////////////////////////////////////////////////////////////// | |
| // | |
| // 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( std::map<string,string>& 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 = std::tolower(c, _stream.getloc()); | |
| 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 |