/// ------------------------------------------------------------------------------------ /// <summary> /// Find out whether a particular property (with a particular type) is cached. /// </summary> /// <param name="hvo">Hvo</param> /// <param name="tag">Tag</param> /// <param name="cpt">is a member of <see cref="CellarModuleDefns"/> (defined /// in CmTypes.h)</param> /// <param name="ws">Writing system id. Ignored unless <paramref name="cpt"/> is kcptMulti</param> /// <returns></returns> /// <remarks>Eventually we may support using kcptNil as 'any' but not yet.</remarks> /// ------------------------------------------------------------------------------------ public bool get_IsPropInCache(int hvo, int tag, int cpt, int ws) { CheckDisposed(); bool fRet = true; CacheKey key; // create the key that fits to the type switch ((CellarModuleDefns)cpt) { case CellarModuleDefns.kcptMultiString: case CellarModuleDefns.kcptMultiBigString: case CellarModuleDefns.kcptMultiUnicode: case CellarModuleDefns.kcptMultiBigUnicode: key = new CacheKeyEx(hvo, tag, ws); break; case CellarModuleDefns.kcptOwningAtom: case CellarModuleDefns.kcptReferenceAtom: key = new CacheKeyEx(hvo, tag, (int)CellarModuleDefns.kcptOwningAtom); break; default: key = new CacheKey(hvo, tag); break; } if (!m_htCache.Contains(key)) fRet = false; else { object obj = m_htCache[key]; // now check if the object has the expected type switch ((CellarModuleDefns)cpt) { case CellarModuleDefns.kcptBoolean: case CellarModuleDefns.kcptInteger: case CellarModuleDefns.kcptNumeric: fRet &= obj is int; break; case CellarModuleDefns.kcptFloat: fRet &= obj is float; break; case CellarModuleDefns.kcptTime: fRet &= (obj is DateTime || obj is long); break; case CellarModuleDefns.kcptGuid: fRet &= obj is Guid; break; case CellarModuleDefns.kcptImage: case CellarModuleDefns.kcptGenDate: // REVIEW (EberhardB): would it be benefical to enable this? // Not implemented yet (i.e. we don't want to break our tests, although // our cache could handle these types) fRet = false; break; case CellarModuleDefns.kcptBinary: fRet &= obj is byte[]; break; case CellarModuleDefns.kcptMultiString: case CellarModuleDefns.kcptMultiBigString: case CellarModuleDefns.kcptMultiUnicode: case CellarModuleDefns.kcptMultiBigUnicode: case CellarModuleDefns.kcptString: case CellarModuleDefns.kcptBigString: fRet &= obj is ITsString; break; case CellarModuleDefns.kcptUnicode: case CellarModuleDefns.kcptBigUnicode: fRet &= obj is string; break; case CellarModuleDefns.kcptOwningAtom: case CellarModuleDefns.kcptReferenceAtom: fRet &= obj is int; break; case CellarModuleDefns.kcptOwningCollection: case CellarModuleDefns.kcptReferenceCollection: case CellarModuleDefns.kcptOwningSequence: case CellarModuleDefns.kcptReferenceSequence: fRet &= obj is int[]; break; case CellarModuleDefns.kcptNil: default: throw new ArgumentException("Not a valid property type"); } } return fRet; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Gets a property from the cache /// </summary> /// <param name="hvo">Hvo</param> /// <param name="tag">Tag</param> /// <param name="other"></param> /// <returns>The object, or <c>null</c> if not in the cache</returns> /// ------------------------------------------------------------------------------------ public object Get(int hvo, int tag, int other) { CheckDisposed(); CacheKeyEx key = new CacheKeyEx(hvo, tag, other); object obj = this[key]; if (obj == null) obj = TryVirtual(key); return obj; }
/// ------------------------------------------------------------------------------------ /// <summary> /// Change the owner of a range of objects in a sequence (given by the indexes /// ihvoStart and ihvoEnd) and insert them in another sequence. The "ord" values /// change accordingly (first one to ihvoDstStart). /// </summary> /// <param name="hvoSrcOwner"></param> /// <param name="tagSrc"></param> /// <param name="hvo"></param> /// <param name="hvoDstOwner"></param> /// <param name="tagDst"></param> /// <param name="ihvoDstStart"></param> /// ------------------------------------------------------------------------------------ public void MoveOwn(int hvoSrcOwner, int tagSrc, int hvo, int hvoDstOwner, int tagDst, int ihvoDstStart) { CheckDisposed(); int iSrcType = m_mdc.GetFieldType((uint) tagSrc); int iDstType = m_mdc.GetFieldType((uint) tagDst); switch (iSrcType) { case (int)FieldType.kcptOwningAtom: CacheKeyEx key = new CacheKeyEx(hvoSrcOwner, tagSrc, (int)CellarModuleDefns.kcptOwningAtom); m_htCache.Remove(key); break; case (int)FieldType.kcptOwningCollection: case (int)FieldType.kcptOwningSequence: object objSrc = Get(hvoSrcOwner, tagSrc); if (objSrc == null) throw new ArgumentException("src not found in cache"); if (objSrc is int[]) { int[] srcVec = (int[])objSrc; int ihvo = GetObjIndex(hvoSrcOwner, tagSrc, hvo); int[] newSrcVec = new int[srcVec.Length - 1]; if (ihvo != 0) Array.Copy(srcVec, 0, newSrcVec, 0, ihvo); if (ihvo + 1 < srcVec.Length) Array.Copy(srcVec, ihvo + 1, newSrcVec, ihvo, srcVec.Length - 1); Set(hvoSrcOwner, tagSrc, newSrcVec); } break; } switch (iDstType) { case (int)FieldType.kcptOwningAtom: CacheObjProp(hvoDstOwner, tagDst, hvo); break; case (int)FieldType.kcptOwningCollection: case (int)FieldType.kcptOwningSequence: object objDst = Get(hvoDstOwner, tagDst); int[] newDstVec = null; if (objDst == null) { newDstVec = new int[1]; } else if (objDst is int[]) { int[] dstVec = (int[])objDst; newDstVec = new int[dstVec.Length + 1]; Array.Copy(dstVec, newDstVec, dstVec.Length); } if (newDstVec != null) { newDstVec[newDstVec.Length - 1] = hvo; Set(hvoDstOwner, tagDst, newDstVec); } break; } SetObjProp(hvo, (int)CmObjectFields.kflidCmObject_Owner, hvoDstOwner); SetInt(hvo, (int)CmObjectFields.kflidCmObject_OwnFlid, tagDst); }