// Copyright (C) 2012-2013 ChaosForge / Kornel Kisielewicz // http://chaosforge.org/ // // This file is part of NV Libraries. // For conditions of distribution and use, see copyright notice in nv.hh #include "nv/lua/lua_path.hh" #include "nv/lua/lua_raw.hh" using namespace nv; lua::path::path( nv::string p ) : m_count(0), m_path( std::move( p ) ) { parse(); } lua::path::path( const char* p ) : m_count(0), m_path( p ) { parse(); } lua::path::path( unsigned i ) : m_count(0) { push( i ); } void lua::path::parse() { size_t start = 0; size_t point = m_path.find('.'); while( point != std::string::npos ) { push( start, point-start ); start = point+1; point = m_path.find( '.', start ); } push( start, m_path.length() - start ); } void lua::path::push( uint32 e ) { m_elements[ m_count ].value = e; m_elements[ m_count ].length = 0; m_count++; } void lua::path::push( uint32 start, uint32 length ) { m_elements[ m_count ].value = start; m_elements[ m_count ].length = length; m_count++; } void lua::path::push( const char* p, uint32 length ) { m_elements[ m_count ].value = m_path.length(); m_elements[ m_count ].length = length; m_path.append( p, length ); m_count++; } void lua::path::push( const std::string& s, uint32 length ) { m_elements[ m_count ].value = m_path.length(); m_elements[ m_count ].length = length; m_path.append( s, 0, length ); m_count++; } bool lua::path::resolve( lua_State* L, bool global /*= true */ ) const { if (m_count == 0) return false; if (global) lua_pushglobaltable( L ); for (int i = 0; i < m_count; ++i ) { if ( lua_istable( L, -1 ) ) { if ( m_elements[i].length > 0 ) { lua_pushlstring( L, m_path.c_str() + m_elements[i].value, m_elements[i].length ); } else { lua_pushunsigned( L, m_elements[i].value ); } lua_gettable( L, -2 ); if (i > 0 || global ) lua_replace( L, -2 ); } else { lua_pop(L, 1); return false; } } return true; } std::string nv::lua::path::to_string() const { std::string result; result.reserve( 2 * m_path.length() ); bool dot = false; for ( const element& e : m_elements ) { if ( dot ) result.append("."); if ( e.length == 0 ) { result.append("[" + nv::to_string( e.value ) + "]" ); dot = false; } else { result.append( m_path, e.value, e.length ); dot = true; } } return result; }