%% %% %CopyrightBegin% %% %% Copyright Ericsson AB 1997-2009. All Rights Reserved. %% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. %% %% 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. %% %% %CopyrightEnd% %% %% -module(asn1ct_name). %%-compile(export_all). -export([name_server_loop/1, start/0, stop/0, push/1, pop/1, curr/1, clear/0, delete/1, active/1, prev/1, next/1, all/1, new/1]). start() -> start_server(asn1_ns, asn1ct_name,name_server_loop,[[]]). stop() -> stop_server(asn1_ns). name_server_loop(Vars) -> %% io:format("name -- ~w~n",[Vars]), receive {From,{current,Variable}} -> From ! {asn1_ns,get_curr(Vars,Variable)}, name_server_loop(Vars); {From,{pop,Variable}} -> From ! {asn1_ns,done}, name_server_loop(pop_var(Vars,Variable)); {From,{push,Variable}} -> From ! {asn1_ns,done}, name_server_loop(push_var(Vars,Variable)); {From,{delete,Variable}} -> From ! {asn1_ns,done}, name_server_loop(delete_var(Vars,Variable)); {From,{new,Variable}} -> From ! {asn1_ns,done}, name_server_loop(new_var(Vars,Variable)); {From,{prev,Variable}} -> From ! {asn1_ns,get_prev(Vars,Variable)}, name_server_loop(Vars); {From,{next,Variable}} -> From ! {asn1_ns,get_next(Vars,Variable)}, name_server_loop(Vars); {From,stop} -> unregister(asn1_ns), From ! {asn1_ns,stopped}, exit(normal) end. active(V) -> case curr(V) of nil -> false; _ -> true end. req(Req) -> asn1_ns ! {self(), Req}, receive {asn1_ns, Reply} -> Reply end. pop(V) -> req({pop,V}). push(V) -> req({push,V}). clear() -> req(stop), start(). curr(V) -> req({current,V}). new(V) -> req({new,V}). delete(V) -> req({delete,V}). prev(V) -> case req({prev,V}) of none -> exit('cant get prev of none'); Rep -> Rep end. next(V) -> case req({next,V}) of none -> exit('cant get next of none'); Rep -> Rep end. all(V) -> Curr = curr(V), if Curr == V -> []; true -> lists:reverse(generate(V,last(Curr),[],0)) end. generate(V,Number,Res,Pos) -> Ell = Pos+1, if Ell > Number -> Res; true -> generate(V,Number,[list_to_atom(lists:concat([V,Ell]))|Res],Ell) end. last(V) -> last2(lists:reverse(atom_to_list(V))). last2(RevL) -> list_to_integer(lists:reverse(get_digs(RevL))). get_digs([H|T]) -> if H < $9+1, H > $0-1 -> [H|get_digs(T)]; true -> [] end. push_var(Vars,Variable) -> case lists:keysearch(Variable,1,Vars) of false -> [{Variable,[0]}|Vars]; {value,{Variable,[Digit|Drest]}} -> NewVars = lists:keydelete(Variable,1,Vars), [{Variable,[Digit,Digit|Drest]}|NewVars] end. pop_var(Vars,Variable) -> case lists:keysearch(Variable,1,Vars) of false -> ok; {value,{Variable,[_Dig]}} -> lists:keydelete(Variable,1,Vars); {value,{Variable,[_Dig|Digits]}} -> NewVars = lists:keydelete(Variable,1,Vars), [{Variable,Digits}|NewVars] end. get_curr([],Variable) -> Variable; get_curr([{Variable,[0|_Drest]}|_Tail],Variable) -> Variable; get_curr([{Variable,[Digit|_Drest]}|_Tail],Variable) -> list_to_atom(lists:concat([Variable,integer_to_list(Digit)])); get_curr([_|Tail],Variable) -> get_curr(Tail,Variable). new_var(Vars,Variable) -> case lists:keysearch(Variable,1,Vars) of false -> [{Variable,[1]}|Vars]; {value,{Variable,[Digit|Drest]}} -> NewVars = lists:keydelete(Variable,1,Vars), [{Variable,[Digit+1|Drest]}|NewVars] end. delete_var(Vars,Variable) -> case lists:keysearch(Variable,1,Vars) of false -> Vars; {value,{Variable,[N]}} when N =< 1 -> lists:keydelete(Variable,1,Vars); {value,{Variable,[Digit|Drest]}} -> case Digit of 0 -> Vars; _ -> NewVars = lists:keydelete(Variable,1,Vars), [{Variable,[Digit-1|Drest]}|NewVars] end end. get_prev(Vars,Variable) -> case lists:keysearch(Variable,1,Vars) of false -> none; {value,{Variable,[Digit|_]}} when Digit =< 1 -> Variable; {value,{Variable,[Digit|_]}} when Digit > 1 -> list_to_atom(lists:concat([Variable, integer_to_list(Digit-1)])); _ -> none end. get_next(Vars,Variable) -> case lists:keysearch(Variable,1,Vars) of false -> list_to_atom(lists:concat([Variable,"1"])); {value,{Variable,[Digit|_]}} when Digit >= 0 -> list_to_atom(lists:concat([Variable, integer_to_list(Digit+1)])); _ -> none end. stop_server(Name) -> stop_server(Name, whereis(Name)). stop_server(_Name, undefined) -> stopped; stop_server(Name, _Pid) -> Name ! {self(), stop}, receive {Name, _} -> stopped end. start_server(Name,Mod,Fun,Args) -> case whereis(Name) of undefined -> case catch register(Name, spawn(Mod,Fun, Args)) of {'EXIT',{badarg,_}} -> start_server(Name,Mod,Fun,Args); _ -> ok end; _Pid -> already_started end.