#line 1 "src/internal_modules/roc_address/io_uri_parse.rl"
/*
* Copyright (c) 2019 Roc Streaming authors
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/

#include "roc_address/io_uri.h"
#include "roc_core/log.h"
#include "roc_core/panic.h"

namespace roc {
	namespace address {
		

#line 17 "build/src/x86_64-pc-linux-gnu/gcc-15.2.1-release/internal_modules/roc_address/io_uri_parse.cpp"
static const signed char _parse_io_uri_actions[] = {
			0, 1, 0, 1, 1, 1, 2, 2,
			3, 4, 0
		};
		
		static const signed char _parse_io_uri_key_offsets[] = {
			0, 0, 7, 14, 15, 16, 18, 26,
			34, 42, 49, 50, 53, 56, 59, 60,
			61, 62, 63, 64, 65, 66, 67, 68,
			70, 0
		};
		
		static const char _parse_io_uri_trans_keys[] = {
			102, 48, 57, 65, 90, 97, 122, 58,
			48, 57, 65, 90, 97, 122, 47, 47,
			35, 63, 58, 105, 48, 57, 65, 90,
			97, 122, 58, 108, 48, 57, 65, 90,
			97, 122, 58, 101, 48, 57, 65, 90,
			97, 122, 58, 48, 57, 65, 90, 97,
			122, 47, 35, 47, 63, 45, 47, 108,
			35, 47, 63, 111, 99, 97, 108, 104,
			111, 115, 116, 47, 35, 63, 0
		};
		
		static const signed char _parse_io_uri_single_lengths[] = {
			0, 1, 1, 1, 1, 2, 2, 2,
			2, 1, 1, 3, 3, 3, 1, 1,
			1, 1, 1, 1, 1, 1, 1, 2,
			0, 0
		};
		
		static const signed char _parse_io_uri_range_lengths[] = {
			0, 3, 3, 0, 0, 0, 3, 3,
			3, 3, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0
		};
		
		static const signed char _parse_io_uri_index_offsets[] = {
			0, 0, 5, 10, 12, 14, 17, 23,
			29, 35, 40, 42, 46, 50, 54, 56,
			58, 60, 62, 64, 66, 68, 70, 72,
			75, 0
		};
		
		static const signed char _parse_io_uri_cond_targs[] = {
			6, 2, 2, 2, 0, 3, 2, 2,
			2, 0, 4, 0, 5, 0, 0, 0,
			23, 3, 7, 2, 2, 2, 0, 3,
			8, 2, 2, 2, 0, 3, 9, 2,
			2, 2, 0, 10, 2, 2, 2, 0,
			11, 23, 0, 12, 0, 23, 24, 13,
			14, 0, 0, 0, 0, 23, 15, 0,
			16, 0, 17, 0, 18, 0, 19, 0,
			20, 0, 21, 0, 22, 0, 13, 0,
			0, 0, 23, 0, 0, 1, 2, 3,
			4, 5, 6, 7, 8, 9, 10, 11,
			12, 13, 14, 15, 16, 17, 18, 19,
			20, 21, 22, 23, 24, 0
		};
		
		static const signed char _parse_io_uri_cond_actions[] = {
			1, 1, 1, 1, 0, 3, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			1, 3, 0, 0, 0, 0, 0, 3,
			0, 0, 0, 0, 0, 3, 0, 0,
			0, 0, 0, 5, 0, 0, 0, 0,
			1, 1, 0, 0, 0, 0, 1, 1,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 1, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 0, 0, 0, 0, 0,
			0, 0, 0, 7, 7, 0
		};
		
		static const signed char _parse_io_uri_eof_trans[] = {
			77, 78, 79, 80, 81, 82, 83, 84,
			85, 86, 87, 88, 89, 90, 91, 92,
			93, 94, 95, 96, 97, 98, 99, 100,
			101, 0
		};
		
		static const int parse_io_uri_start = 1;
		static const int parse_io_uri_first_final = 23;
		static const int parse_io_uri_error = 0;
		
		static const int parse_io_uri_en_main = 1;
		
		
#line 19 "src/internal_modules/roc_address/io_uri_parse.rl"

		
		namespace {
			
			bool parse_io_uri_imp(const char* str, IoUri& result) {
				if (!str) {
					roc_log(LogError, "parse io uri: input string is null");
					return false;
				}
				
				result.clear();
				
				// for ragel
				const char* p = str;
				const char *pe = str + strlen(str);
				
				const char *eof = pe;
				int cs = 0;
				
				// for start_token
				const char* start_p = NULL;
				
				// parse result
				bool success = false;
				

#line 133 "build/src/x86_64-pc-linux-gnu/gcc-15.2.1-release/internal_modules/roc_address/io_uri_parse.cpp"
	{
					cs = (int)parse_io_uri_start;
				}

#line 136 "build/src/x86_64-pc-linux-gnu/gcc-15.2.1-release/internal_modules/roc_address/io_uri_parse.cpp"
	{
					int _klen;
					unsigned int _trans = 0;
					const char * _keys;
					const signed char * _acts;
					unsigned int _nacts;
					_resume: {}
					if ( p == pe && p != eof )
						goto _out;
					if ( p == eof ) {
						if ( _parse_io_uri_eof_trans[cs] > 0 ) {
							_trans = (unsigned int)_parse_io_uri_eof_trans[cs] - 1;
						}
					}
					else {
						_keys = ( _parse_io_uri_trans_keys + (_parse_io_uri_key_offsets[cs]));
						_trans = (unsigned int)_parse_io_uri_index_offsets[cs];
						
						_klen = (int)_parse_io_uri_single_lengths[cs];
						if ( _klen > 0 ) {
							const char *_lower = _keys;
							const char *_upper = _keys + _klen - 1;
							const char *_mid;
							while ( 1 ) {
								if ( _upper < _lower ) {
									_keys += _klen;
									_trans += (unsigned int)_klen;
									break;
								}
								
								_mid = _lower + ((_upper-_lower) >> 1);
								if ( ( (*( p))) < (*( _mid)) )
									_upper = _mid - 1;
								else if ( ( (*( p))) > (*( _mid)) )
									_lower = _mid + 1;
								else {
									_trans += (unsigned int)(_mid - _keys);
									goto _match;
								}
							}
						}
						
						_klen = (int)_parse_io_uri_range_lengths[cs];
						if ( _klen > 0 ) {
							const char *_lower = _keys;
							const char *_upper = _keys + (_klen<<1) - 2;
							const char *_mid;
							while ( 1 ) {
								if ( _upper < _lower ) {
									_trans += (unsigned int)_klen;
									break;
								}
								
								_mid = _lower + (((_upper-_lower) >> 1) & ~1);
								if ( ( (*( p))) < (*( _mid)) )
									_upper = _mid - 2;
								else if ( ( (*( p))) > (*( _mid + 1)) )
									_lower = _mid + 2;
								else {
									_trans += (unsigned int)((_mid - _keys)>>1);
									break;
								}
							}
						}
						
						_match: {}
					}
					cs = (int)_parse_io_uri_cond_targs[_trans];
					
					if ( _parse_io_uri_cond_actions[_trans] != 0 ) {
						
						_acts = ( _parse_io_uri_actions + (_parse_io_uri_cond_actions[_trans]));
						_nacts = (unsigned int)(*( _acts));
						_acts += 1;
						while ( _nacts > 0 ) {
							switch ( (*( _acts)) )
							{
								case 0:  {
										{
#line 45 "src/internal_modules/roc_address/io_uri_parse.rl"
										
										start_p = p;
									}
									
#line 220 "build/src/x86_64-pc-linux-gnu/gcc-15.2.1-release/internal_modules/roc_address/io_uri_parse.cpp"

									break; 
								}
								case 1:  {
										{
#line 49 "src/internal_modules/roc_address/io_uri_parse.rl"
										
										if (!result.set_scheme(start_p, p - start_p)) {
											roc_log(LogError, "parse io uri: invalid scheme");
											return false;
										}
									}
									
#line 233 "build/src/x86_64-pc-linux-gnu/gcc-15.2.1-release/internal_modules/roc_address/io_uri_parse.cpp"

									break; 
								}
								case 2:  {
										{
#line 56 "src/internal_modules/roc_address/io_uri_parse.rl"
										
										const char* scheme = "file";
										
										if (!result.set_scheme(scheme, strlen(scheme))) {
											roc_log(LogError, "parse io uri: invalid scheme");
											return false;
										}
									}
									
#line 248 "build/src/x86_64-pc-linux-gnu/gcc-15.2.1-release/internal_modules/roc_address/io_uri_parse.cpp"

									break; 
								}
								case 3:  {
										{
#line 65 "src/internal_modules/roc_address/io_uri_parse.rl"
										
										if (!result.set_encoded_path(start_p, p - start_p)) {
											roc_log(LogError, "parse io uri: invalid path");
											return false;
										}
									}
									
#line 261 "build/src/x86_64-pc-linux-gnu/gcc-15.2.1-release/internal_modules/roc_address/io_uri_parse.cpp"

									break; 
								}
								case 4:  {
										{
#line 92 "src/internal_modules/roc_address/io_uri_parse.rl"
										success = true; }
									
#line 269 "build/src/x86_64-pc-linux-gnu/gcc-15.2.1-release/internal_modules/roc_address/io_uri_parse.cpp"

									break; 
								}
							}
							_nacts -= 1;
							_acts += 1;
						}
						
					}
					
					if ( p == eof ) {
						if ( cs >= 23 )
							goto _out;
					}
					else {
						if ( cs != 0 ) {
							p += 1;
							goto _resume;
						}
					}
					_out: {}
				}
				
#line 97 "src/internal_modules/roc_address/io_uri_parse.rl"

				
				if (!success) {
					roc_log(LogError,
					"parse io uri: expected one of:\n"
					" 'DEVICE_TYPE://DEVICE_NAME',\n"
					" 'file:///ABS/PATH',\n"
					" 'file://localhost/ABS/PATH',\n"
					" 'file:/ABS/PATH',\n"
					" 'file:REL/PATH',\n"
					" 'file://-',\n"
					" 'file:-',\n"
					" got '%s'",
					str);
					return false;
				}
				
				return true;
			}
			
		} // namespace
		
		bool parse_io_uri(const char* str, IoUri& result) {
			if (!parse_io_uri_imp(str, result)) {
				result.clear();
				return false;
			}
			return true;
		}
		
	} // namespace address
} // namespace roc
