| /////////////////////////////////////////////////////////////////////////////// |
| // |
| // 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 |