blob: 4eaa98e8324b4d925e10a3fb6133a0f9a439ec56 [file] [log] [blame]
///////////////////////////////////////////////////////////////////////////////
//
// 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