// Copyright (C) 2012-2015 ChaosForge Ltd // http://chaosforge.org/ // // This file is part of Nova libraries. // For conditions of distribution and use, see copying.txt file in root folder. #include "nv/lua/lua_path.hh" #include "nv/lua/lua_raw.hh" using namespace nv; void lua::path::parse() { if ( m_elements[0].length == 0 || m_elements[0].str == nullptr ) return; string_view spath( m_elements[0].str, m_elements[0].length ); m_count = 0; size_t point = spath.find( '.' ); while ( point != string_view::npos ) { m_elements[m_count].str = spath.data(); m_elements[m_count].length = point; m_count++; spath.remove_prefix( point + 1 ); point = spath.find( '.' ); } m_elements[m_count].str = spath.data(); m_elements[m_count].length = spath.length(); m_count++; } void lua::path::push( nv::uint32 value ) { m_elements[ m_count ].value = value; m_elements[ m_count ].length = 0; m_count++; } void nv::lua::path::push( string_view p ) { m_elements[ m_count ].str = p.data(); m_elements[ m_count ].length = p.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 ( uint32 i = 0; i < m_count; ++i ) { if ( lua_istable( L, -1 ) ) { if ( m_elements[i].length > 0 ) { lua_pushlstring( L, m_elements[i].str, 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 { char buffer[64]; char* start = buffer; char* current = buffer; bool dot = false; bool oos = false; for ( const element& e : m_elements ) { if ( current - start > 48 ) { oos = true; break; } if ( dot ) *current++ = '.'; if ( e.length == 0 ) { *current++ = '['; current += uint32_to_buffer( e.value, current ); *current++ = ']'; dot = false; } else { if ( size_t(current - start) + e.length > 60 ) { oos = true; break; } nvmemcpy( current, e.str, e.length ); current += e.length; dot = true; } } if (oos) { *current++ = '.'; *current++ = '.'; *current++ = '.'; } *current++ = '\0'; return std::string( buffer, size_t(current - start - 1) ); }