/* *---------------------------------------------------------------------- * * SetNsNameFromAny -> setNsNameFromAny * * Attempt to generate a nsName internal representation for a * TclObject. * * Results: * Returns if the value could be converted to a proper * namespace reference. Otherwise, raises TclException. * * Side effects: * If successful, the object is made a nsName object. Its internal rep * is set to point to a ResolvedNsName, which contains a cached pointer * to the Namespace. Reference counts are kept on both the * ResolvedNsName and the Namespace, so we can keep track of their * usage and free them when appropriate. * *---------------------------------------------------------------------- */ private static void setNsNameFromAny(Interp interp, TclObject tobj) { string name; Namespace ns; ResolvedNsName resName; // Java does not support passing an address so we pass // an array of size 1 and then assign arr[0] to the value Namespace[] nsArr = new Namespace[1]; Namespace[] dummy1Arr = new Namespace[1]; string[] dummy2Arr = new string[1]; // Get the string representation. name = tobj.ToString(); // Look for the namespace "name" in the current namespace. If there is // an error parsing the (possibly qualified) name, return an error. // If the namespace isn't found, we convert the object to an nsName // object with a null ResolvedNsName internal rep. getNamespaceForQualName(interp, name, null, TCL.VarFlag.FIND_ONLY_NS, nsArr, dummy1Arr, dummy1Arr, dummy2Arr); // Get the values out of the arrays! ns = nsArr[0]; // If we found a namespace, then create a new ResolvedNsName structure // that holds a reference to it. if (ns != null) { Namespace currNs = getCurrentNamespace(interp); ns.refCount++; resName = new ResolvedNsName(); resName.ns = ns; resName.nsId = ns.nsId; resName.refNs = currNs; resName.refCount = 1; } else { resName = null; } // By setting the new internal rep we free up the old one. // FIXME : should a NamespaceCmd wrap a ResolvedNsName? // this is confusing because it seems like the C code uses // a ResolvedNsName like it is the InternalRep. NamespaceCmd wrap = new NamespaceCmd(); wrap.otherValue = resName; tobj.InternalRep = wrap; return ; }
/* *---------------------------------------------------------------------- * * FreeNsNameInternalRep -> dispose * * Frees the resources associated with a object's internal * representation. See src/tcljava/tcl/lang/InternalRep.java * * Results: * None. * * Side effects: * Decrements the ref count of any Namespace structure pointed * to by the nsName's internal representation. If there are no more * references to the namespace, it's structure will be freed. * *---------------------------------------------------------------------- */ public void dispose() { bool debug; System.Diagnostics.Debug.WriteLine("dispose() called for namespace object " + (otherValue == null?null:otherValue.ns)); ResolvedNsName resName = otherValue; Namespace ns; // Decrement the reference count of the namespace. If there are no // more references, free it up. if (resName != null) { resName.refCount--; if (resName.refCount == 0) { // Decrement the reference count for the cached namespace. If // the namespace is dead, and there are no more references to // it, free it. ns = resName.ns; ns.refCount--; if ((ns.refCount == 0) && ((ns.flags & NS_DEAD) != 0)) { free(ns); } otherValue = null; } } }