public byte[] GetBinary(int columnIndex, int rowIndex)
        {
            this.CheckColumn(columnIndex, ColumnType.Binary, null);

            var(leaf, indexInLeaf) = this.GetFromBpTree(columnIndex, rowIndex);

            var leafHeader = new RealmArrayHeader(leaf);
            var isBig      = leafHeader.ContextFlag;

            byte[] value;
            if (!isBig)
            {
                // 要素はすべて64バイト以下
                // https://github.com/realm/realm-core/blob/v5.12.7/src/realm/column_binary.cpp#L31
                value = new RealmArrayBinary(leaf)[indexInLeaf];
            }
            else
            {
                value = new RealmArrayBigBlobs(leaf)[indexInLeaf];
            }

            var nullable = this.Spec.GetColumn(columnIndex).Nullable;

            return(value == null && !nullable ? new byte[0] : value);
        }
        public byte[] this[int index]
        {
            get
            {
                var blobRefValue = (ulong)this._array[index];

                // 0 は null
                if (blobRefValue == 0)
                {
                    return(null);
                }

                var blobArrayRef = this.Ref.NewRef(blobRefValue);
                var blobHeader   = new RealmArrayHeader(blobArrayRef);

                // ContextFlag、一体何者なんだ……?
                // https://github.com/realm/realm-core/blob/v5.12.7/src/realm/array_blobs_big.hpp#L109
                if (blobHeader.ContextFlag)
                {
                    return(null);
                }

                var len  = blobHeader.Size;
                var data = new byte[len];
                // ヘッダーの後 Size バイトが実際のデータ
                blobArrayRef.ReadBytes(RealmArrayHeader.HeaderSize, data, 0, len);
                return(data);
            }
        }
        public string GetString(int columnIndex, int rowIndex)
        {
            var spec     = this.Spec.GetColumn(columnIndex);
            var nullable = spec.Nullable;

            if (spec.Type == ColumnType.String)
            {
                var(leaf, indexInLeaf) = this.GetFromBpTree(columnIndex, rowIndex);

                var leafHeader  = new RealmArrayHeader(leaf);
                var longStrings = leafHeader.HasRefs;
                var isBig       = leafHeader.ContextFlag;

                string value;
                if (!longStrings)
                {
                    // 要素はすべて15バイト以下
                    // https://github.com/realm/realm-core/blob/v5.12.7/src/realm/column_string.cpp#L38-L39
                    value = new RealmArrayString(leaf, nullable)[indexInLeaf];
                }
                else if (!isBig)
                {
                    // 要素はすべて63バイト以下
                    value = new RealmArrayStringLong(leaf, nullable)[indexInLeaf];
                }
                else
                {
                    value = new RealmArrayBigBlobs(leaf).GetString(indexInLeaf);
                }

                return(value == null && !nullable ? "" : value);
            }
            else if (spec.Type == ColumnType.StringEnum)
            {
                // Table::optimize (各種言語バインディングからは未使用)で
                // 半分以上の値が重複している String カラムを圧縮したときに誕生する
                throw new NotImplementedException("StringEnum");
            }
            else
            {
                throw new InvalidOperationException($"このカラムの型は {spec.Type} です。");
            }
        }
Example #4
0
 public RealmArray(ReferenceAccessor @ref)
 {
     this.Ref    = @ref;
     this.Header = new RealmArrayHeader(@ref);
 }