    001/*-
    002 *******************************************************************************
    003 * Copyright (c) 2011, 2016 Diamond Light Source Ltd.
    004 * All rights reserved. This program and the accompanying materials
    005 * are made available under the terms of the Eclipse Public License v1.0
    006 * which accompanies this distribution, and is available at
    007 * http://www.eclipse.org/legal/epl-v10.html
    008 *
    009 * Contributors:
    010 *    Peter Chang - initial API and implementation and/or initial documentation
    011 *******************************************************************************/
    012
    013// This is generated from DoubleDataset.java by fromdouble.py
    014
    015package org.eclipse.january.dataset;
    016
    017import java.util.ArrayList;
    018import java.util.Arrays;
    019import java.util.List;
    020import java.util.Set;
    021import java.util.TreeSet;
    022
    023import org.eclipse.january.metadata.StatisticsMetadata;
    024
    025
    026/**
    027 * Extend dataset for String values // PRIM_TYPE
    028 */
    029public class StringDatasetBase extends AbstractDataset {
    030        // pin UID to base class
    031        private static final long serialVersionUID = Dataset.serialVersionUID;
    032
    033        protected String[] data; // subclass alias // PRIM_TYPE
    034
    035        @Override
    036        protected void setData() {
    037                data = (String[]) odata; // PRIM_TYPE
    038        }
    039
    040        protected static String[] createArray(final int size) { // PRIM_TYPE
    041                String[] array = null; // PRIM_TYPE
    042
    043                try {
    044                        array = new String[size]; // PRIM_TYPE
    045                } catch (OutOfMemoryError e) {
    046                        logger.error("The size of the dataset ({}) that is being created is too large "
    047                                        + "and there is not enough memory to hold it.", size);
    048                        throw new OutOfMemoryError("The dimensions given are too large, and there is "
    049                                        + "not enough memory available in the Java Virtual Machine");
    050                }
    051                return array;
    052        }
    053
    054        @Override
    055        public int getDType() {
    056                return STRING; // DATA_TYPE
    057        }
    058
    059        /**
    060         * Create a null dataset
    061         */
    062        StringDatasetBase() {
    063        }
    064
    065        /**
    066         * Create a zero-filled dataset of given shape
    067         * @param shape
    068         */
    069        StringDatasetBase(final int... shape) {
    070                if (shape != null) {
    071                        size = ShapeUtils.calcSize(shape);
    072                        this.shape = shape.clone();
    073
    074                        try {
    075                                odata = data = createArray(size);
    076                        } catch (Throwable t) {
    077                                logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    078                                throw new IllegalArgumentException(t);
    079                        }
    080                }
    081        }
    082
    083        /**
    084         * Create a dataset using given data
    085         * @param data
    086         * @param shape
    087         *            (can be null to create 1D dataset)
    088         */
    089        StringDatasetBase(final String[] data, int... shape) { // PRIM_TYPE
    090                if (data == null) {
    091                        throw new IllegalArgumentException("Data must not be null");
    092                }
    093                if (shape == null || shape.length == 0) {
    094                        shape = new int[] { data.length };
    095                }
    096                size = ShapeUtils.calcSize(shape);
    097                if (size != data.length) {
    098                        throw new IllegalArgumentException(String.format("Shape %s is not compatible with size of data array, %d",
    099                                        Arrays.toString(shape), data.length));
    100                }
    101                this.shape = size == 0 ? null : shape.clone();
    102
    103                odata = this.data = data;
    104        }
    105
    106        /**
    107         * Copy a dataset
    108         * @param dataset
    109         */
    110        StringDatasetBase(final StringDatasetBase dataset) {
    111                copyToView(dataset, this, true, true);
    112
    113                try {
    114                        if (dataset.stride == null) {
    115                                if (dataset.data != null) {
    116                                        odata = data = dataset.data.clone();
    117                                }
    118                        } else {
    119                                offset = 0;
    120                                stride = null;
    121                                base = null;
    122                                odata = data = createArray(size);
    123
    124                                IndexIterator iter = dataset.getIterator();
    125                                for (int i = 0; iter.hasNext(); i++) {
    126                                        data[i] = dataset.data[iter.index];
    127                                }
    128                        }
    129                } catch (Throwable t) {
    130                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    131                        throw new IllegalArgumentException(t);
    132                }
    133        }
    134
    135        /**
    136         * Copy and cast a dataset to this class type
    137         * @param dataset
    138         */
    139        StringDatasetBase(final Dataset dataset) {
    140                copyToView(dataset, this, true, false);
    141                offset = 0;
    142                stride = null;
    143                base = null;
    144                try {
    145                        odata = data = createArray(size);
    146                } catch (Throwable t) {
    147                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    148                        throw new IllegalArgumentException(t);
    149                }
    150                IndexIterator iter = dataset.getIterator();
    151                for (int i = 0; iter.hasNext(); i++) {
    152                        data[i] = dataset.getStringAbs(iter.index); // GET_ELEMENT_WITH_CAST
    153                }
    154        }
    155
    156        @Override
    157        public boolean equals(Object obj) {
    158                if (this == obj) {
    159                        return true;
    160                }
    161
    162                if (obj == null) {
    163                        return false;
    164                }
    165
    166                if (!getClass().equals(obj.getClass())) {
    167                        if (getRank() == 0) { // for zero-rank datasets
    168                                return obj.equals(getObjectAbs(offset));
    169                        }
    170                        return false;
    171                }
    172
    173                StringDatasetBase other = (StringDatasetBase) obj;
    174                if (size != other.size) {
    175                        return false;
    176                }
    177                if (!Arrays.equals(shape, other.shape)) {
    178                        return false;
    179                }
    180                if (data == other.data && stride == null && other.stride == null) {
    181                        return true;
    182                }
    183
    184                IndexIterator iter = getIterator();
    185                IndexIterator oiter = other.getIterator();
    186                while (iter.hasNext() && oiter.hasNext()) {
    187                        if (!data[iter.index].equals(other.data[oiter.index])) { // OBJECT_UNEQUAL
    188                                return false;
    189                        }
    190                }
    191                return true;
    192        }
    193
    194        @Override
    195        public int hashCode() {
    196                return super.hashCode();
    197        }
    198
    199        @Override
    200        public StringDatasetBase clone() {
    201                return new StringDatasetBase(this);
    202        }
    203
    204        /**
    205         * Create a dataset from an object which could be a Java list, array (of arrays...) or Number. Ragged
    206         * sequences or arrays are padded with zeros.
    207         *
    208         * @param obj
    209         * @return dataset with contents given by input
    210         */
    211        static StringDatasetBase createFromObject(final Object obj) {
    212                StringDatasetBase result = new StringDatasetBase();
    213
    214                if (obj != null) {
    215                        result.shape = ShapeUtils.getShapeFromObject(obj);
    216                        result.size = ShapeUtils.calcSize(result.shape);
    217
    218                        try {
    219                                result.odata = result.data = createArray(result.size);
    220                        } catch (Throwable t) {
    221                                logger.error("Could not create a dataset of shape {}", Arrays.toString(result.shape), t);
    222                                throw new IllegalArgumentException(t);
    223                        }
    224
    225                        int[] pos = new int[result.shape.length];
    226                        result.fillData(obj, 0, pos);
    227                }
    228
    229                return result;
    230        }
    231
    232        /**
    233         * @param shape
    234         * @return a dataset filled with ones
    235         */
    236        static StringDatasetBase ones(final int... shape) {
    237                return new StringDatasetBase(shape).fill(1);
    238        }
    239
    240        @Override
    241        public StringDatasetBase fill(final Object obj) {
    242                setDirty();
    243                String dv = obj.toString(); // PRIM_TYPE // FROM_OBJECT
    244                IndexIterator iter = getIterator();
    245                while (iter.hasNext()) {
    246                        data[iter.index] = dv;
    247                }
    248
    249                return this;
    250        }
    251
    252        /**
    253         * This is a typed version of {@link #getBuffer()}
    254         * @return data buffer as linear array
    255         */
    256        public String[] getData() { // PRIM_TYPE
    257                return data;
    258        }
    259
    260        @Override
    261        protected int getBufferLength() {
    262                if (data == null)
    263                        return 0;
    264                return data.length;
    265        }
    266
    267        @Override
    268        public StringDatasetBase getView(boolean deepCopyMetadata) {
    269                StringDatasetBase view = new StringDatasetBase();
    270                copyToView(this, view, true, deepCopyMetadata);
    271                view.setData();
    272                return view;
    273        }
    274
    275        /**
    276         * Get a value from an absolute index of the internal array. This is an internal method with no checks so can be
    277         * dangerous. Use with care or ideally with an iterator.
    278         *
    279         * @param index
    280         *            absolute index
    281         * @return value
    282         */
    283        public String getAbs(final int index) { // PRIM_TYPE
    284                return data[index];
    285        }
    286
    287        @Override
    288        public boolean getElementBooleanAbs(final int index) {
    289                return false;
    290        }
    291
    292        @Override
    293        public double getElementDoubleAbs(final int index) {
    294                return 0;
    295        }
    296
    297        @Override
    298        public long getElementLongAbs(final int index) {
    299                return 0;
    300        }
    301
    302        @Override
    303        public Object getObjectAbs(final int index) {
    304                return data[index];
    305        }
    306
    307        @Override
    308        public String getStringAbs(final int index) {
    309                return stringFormat == null ?  data[index] : // FORMAT_STRING
    310                        stringFormat.format(data[index]);
    311        }
    312
    313        /**
    314         * Set a value at absolute index in the internal array. This is an internal method with no checks so can be
    315         * dangerous. Use with care or ideally with an iterator.
    316         *
    317         * @param index
    318         *            absolute index
    319         * @param val
    320         *            new value
    321         */
    322        public void setAbs(final int index, final String val) { // PRIM_TYPE
    323                setDirty();
    324                data[index] = val;
    325        }
    326
    327        @Override
    328        protected void setItemDirect(final int dindex, final int sindex, final Object src) {
    329                setDirty();
    330                String[] dsrc = (String[]) src; // PRIM_TYPE
    331                data[dindex] = dsrc[sindex];
    332        }
    333
    334        @Override
    335        public void setObjectAbs(final int index, final Object obj) {
    336                if (index < 0 || index > data.length) {
    337                        throw new IndexOutOfBoundsException("Index given is outside dataset");
    338                }
    339
    340                setAbs(index, obj.toString()); // FROM_OBJECT
    341        }
    342
    343        /**
    344         * @return item in first position
    345         * @since 2.0
    346         */
    347        public String get() { // PRIM_TYPE
    348                return data[getFirst1DIndex()];
    349        }
    350
    351        /**
    352         * @param i
    353         * @return item in given position
    354         */
    355        public String get(final int i) { // PRIM_TYPE
    356                return data[get1DIndex(i)];
    357        }
    358
    359        /**
    360         * @param i
    361         * @param j
    362         * @return item in given position
    363         */
    364        public String get(final int i, final int j) { // PRIM_TYPE
    365                return data[get1DIndex(i, j)];
    366        }
    367
    368        /**
    369         * @param pos
    370         * @return item in given position
    371         */
    372        public String get(final int... pos) { // PRIM_TYPE
    373                return data[get1DIndex(pos)];
    374        }
    375
    376        @Override
    377        public Object getObject() {
    378                return get(); // CLASS_TYPE
    379        }
    380
    381        @Override
    382        public Object getObject(final int i) {
    383                return get(i); // CLASS_TYPE
    384        }
    385
    386        @Override
    387        public Object getObject(final int i, final int j) {
    388                return get(i, j); // CLASS_TYPE
    389        }
    390
    391        @Override
    392        public Object getObject(final int... pos) {
    393                return get(pos); // CLASS_TYPE
    394        }
    395
    396        @Override
    397        public String getString() {
    398                return getStringAbs(getFirst1DIndex());
    399        }
    400
    401        @Override
    402        public String getString(final int i) {
    403                return getStringAbs(get1DIndex(i));
    404        }
    405
    406        @Override
    407        public String getString(final int i, final int j) {
    408                return getStringAbs(get1DIndex(i, j));
    409        }
    410
    411        @Override
    412        public String getString(final int... pos) {
    413                return getStringAbs(get1DIndex(pos));
    414        }
    415
    416        @Override
    417        public double getDouble() {
    418                return 0;
    419        }
    420
    421        @Override
    422        public double getDouble(final int i) {
    423                return 0;
    424        }
    425
    426        @Override
    427        public double getDouble(final int i, final int j) {
    428                return 0;
    429        }
    430
    431        @Override
    432        public double getDouble(final int... pos) {
    433                return 0;
    434        }
    435
    436        @Override
    437        public float getFloat() {
    438                return 0;
    439        }
    440
    441        @Override
    442        public float getFloat(final int i) {
    443                return 0;
    444        }
    445
    446        @Override
    447        public float getFloat(final int i, final int j) {
    448                return 0;
    449        }
    450
    451        @Override
    452        public float getFloat(final int... pos) {
    453                return 0;
    454        }
    455
    456        @Override
    457        public long getLong() {
    458                return 0;
    459        }
    460
    461        @Override
    462        public long getLong(final int i) {
    463                return 0;
    464        }
    465
    466        @Override
    467        public long getLong(final int i, final int j) {
    468                return 0;
    469        }
    470
    471        @Override
    472        public long getLong(final int... pos) {
    473                return 0;
    474        }
    475
    476        @Override
    477        public int getInt() {
    478                return 0;
    479        }
    480
    481        @Override
    482        public int getInt(final int i) {
    483                return 0;
    484        }
    485
    486        @Override
    487        public int getInt(final int i, final int j) {
    488                return 0;
    489        }
    490
    491        @Override
    492        public int getInt(final int... pos) {
    493                return 0;
    494        }
    495
    496        @Override
    497        public short getShort() {
    498                return 0;
    499        }
    500
    501        @Override
    502        public short getShort(final int i) {
    503                return 0;
    504        }
    505
    506        @Override
    507        public short getShort(final int i, final int j) {
    508                return 0;
    509        }
    510
    511        @Override
    512        public short getShort(final int... pos) {
    513                return 0;
    514        }
    515
    516        @Override
    517        public byte getByte() {
    518                return 0;
    519        }
    520
    521        @Override
    522        public byte getByte(final int i) {
    523                return 0;
    524        }
    525
    526        @Override
    527        public byte getByte(final int i, final int j) {
    528                return 0;
    529        }
    530
    531        @Override
    532        public byte getByte(final int... pos) {
    533                return 0;
    534        }
    535
    536        @Override
    537        public boolean getBoolean() {
    538                return false;
    539        }
    540
    541        @Override
    542        public boolean getBoolean(final int i) {
    543                return false;
    544        }
    545
    546        @Override
    547        public boolean getBoolean(final int i, final int j) {
    548                return false;
    549        }
    550
    551        @Override
    552        public boolean getBoolean(final int... pos) {
    553                return false;
    554        }
    555
    556        /**
    557         * Sets the value at first point to the passed value. The dataset must not be null
    558         *
    559         * @param value
    560         * @since 2.0
    561         */
    562        public void setItem(final String value) { // PRIM_TYPE
    563                setAbs(getFirst1DIndex(), value);
    564        }
    565
    566        /**
    567         * Sets the value at a particular point to the passed value. The dataset must be 1D
    568         *
    569         * @param value
    570         * @param i
    571         */
    572        public void setItem(final String value, final int i) { // PRIM_TYPE
    573                setAbs(get1DIndex(i), value);
    574        }
    575
    576        /**
    577         * Sets the value at a particular point to the passed value. The dataset must be 2D
    578         *
    579         * @param value
    580         * @param i
    581         * @param j
    582         */
    583        public void setItem(final String value, final int i, final int j) { // PRIM_TYPE
    584                setAbs(get1DIndex(i, j), value);
    585        }
    586
    587        /**
    588         * Sets the value at a particular point to the passed value
    589         *
    590         * @param value
    591         * @param pos
    592         */
    593        public void setItem(final String value, final int... pos) { // PRIM_TYPE
    594                setAbs(get1DIndex(pos), value);
    595        }
    596
    597        @Override
    598        public void set(final Object obj) {
    599                setItem(obj.toString()); // FROM_OBJECT
    600        }
    601
    602        @Override
    603        public void set(final Object obj, final int i) {
    604                setItem(obj.toString(), i); // FROM_OBJECT
    605        }
    606
    607        @Override
    608        public void set(final Object obj, final int i, final int j) {
    609                setItem(obj.toString(), i, j); // FROM_OBJECT
    610        }
    611
    612        @Override
    613        public void set(final Object obj, int... pos) {
    614                if (pos == null || (pos.length == 0 && shape.length > 0)) {
    615                        pos = new int[shape.length];
    616                }
    617
    618                setItem(obj.toString(), pos); // FROM_OBJECT
    619        }
    620
    621        @Override
    622        public void resize(int... newShape) {
    623                setDirty();
    624                final IndexIterator iter = getIterator();
    625                final int nsize = ShapeUtils.calcSize(newShape);
    626                final String[] ndata; // PRIM_TYPE
    627                try {
    628                        ndata = createArray(nsize);
    629                } catch (Throwable t) {
    630                        logger.error("Could not create a dataset of shape {}", Arrays.toString(shape), t);
    631                        throw new IllegalArgumentException(t);
    632                }
    633                for (int i = 0; iter.hasNext() && i < nsize; i++) {
    634                        ndata[i] = data[iter.index];
    635                }
    636
    637                odata = data = ndata;
    638                size = nsize;
    639                shape = newShape;
    640                stride = null;
    641                offset = 0;
    642                base = null;
    643        }
    644
    645        @Override
    646        public StringDatasetBase sort(Integer axis) {
    647                setDirty();
    648                if (axis == null) {
    649                        if (stride == null) {
    650                                Arrays.sort(data);
    651                        } else {
    652                                StringDatasetBase ads = clone().sort(null);
    653                                setSlicedView(getView(false), ads);
    654                        }
    655                } else {
    656                        axis = checkAxis(axis);
    657
    658                        StringDatasetBase ads = new StringDatasetBase(shape[axis]);
    659                        PositionIterator pi = getPositionIterator(axis);
    660                        int[] pos = pi.getPos();
    661                        boolean[] hit = pi.getOmit();
    662                        while (pi.hasNext()) {
    663                                copyItemsFromAxes(pos, hit, ads);
    664                                Arrays.sort(ads.data);
    665                                setItemsOnAxes(pos, hit, ads.data);
    666                        }
    667                }
    668                return this;
    669                // throw new UnsupportedOperationException("Cannot sort dataset"); // BOOLEAN_USE
    670        }
    671
    672        @Override
    673        public StringDatasetBase getUniqueItems() {
    674                Set<String> set = new TreeSet<String>(); // CLASS_TYPE
    675                IndexIterator it = getIterator();
    676                while (it.hasNext()) {
    677                        set.add(data[it.index]);
    678                }
    679
    680                StringDataset u = new StringDataset(set.size()); // CLASS_TYPE
    681                int i = 0;
    682                String[] udata = u.getData(); // PRIM_TYPE
    683                for (String v : set) { // CLASS_TYPE
    684                        udata[i++] = v;
    685                }
    686                return u;
    687        }
    688
    689        @Override
    690        public StringDatasetBase getSlice(final SliceIterator siter) {
    691                StringDatasetBase result = new StringDatasetBase(siter.getShape());
    692                String[] rdata = result.data; // PRIM_TYPE
    693
    694                for (int i = 0; siter.hasNext(); i++)
    695                        rdata[i] = data[siter.index];
    696
    697                result.setName(name + BLOCK_OPEN + Slice.createString(siter.shape, siter.start, siter.stop, siter.step) + BLOCK_CLOSE);
    698                return result;
    699        }
    700
    701        @Override
    702        public void fillDataset(Dataset result, IndexIterator iter) {
    703                IndexIterator riter = result.getIterator();
    704                result.setDirty();
    705
    706                String[] rdata = ((StringDatasetBase) result).data; // PRIM_TYPE
    707
    708                while (riter.hasNext() && iter.hasNext()) {
    709                        rdata[riter.index] = data[iter.index];
    710                }
    711        }
    712
    713        @Override
    714        public StringDatasetBase setByBoolean(final Object obj, Dataset selection) {
    715                setDirty();
    716                if (obj instanceof Dataset) {
    717                        final Dataset ds = (Dataset) obj;
    718                        final int length = ((Number) selection.sum()).intValue();
    719                        if (length != ds.getSize()) {
    720                                throw new IllegalArgumentException(
    721                                                "Number of true items in selection does not match number of items in dataset");
    722                        }
    723
    724                        final IndexIterator oiter = ds.getIterator();
    725                        final BooleanIterator biter = getBooleanIterator(selection);
    726
    727                        while (biter.hasNext() && oiter.hasNext()) {
    728                                data[biter.index] = ds.getStringAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    729                        }
    730                } else {
    731                        final String dv = obj.toString(); // PRIM_TYPE // FROM_OBJECT
    732                        final BooleanIterator biter = getBooleanIterator(selection);
    733
    734                        while (biter.hasNext()) {
    735                                data[biter.index] = dv;
    736                        }
    737                }
    738                return this;
    739        }
    740
    741        @Override
    742        public StringDatasetBase setBy1DIndex(final Object obj, final Dataset index) {
    743                setDirty();
    744                if (obj instanceof Dataset) {
    745                        final Dataset ds = (Dataset) obj;
    746                        if (index.getSize() != ds.getSize()) {
    747                                throw new IllegalArgumentException(
    748                                                "Number of items in index dataset does not match number of items in dataset");
    749                        }
    750
    751                        final IndexIterator oiter = ds.getIterator();
    752                        final IntegerIterator iter = new IntegerIterator(index, size);
    753
    754                        while (iter.hasNext() && oiter.hasNext()) {
    755                                data[iter.index] = ds.getStringAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    756                        }
    757                } else {
    758                        final String dv = obj.toString(); // PRIM_TYPE // FROM_OBJECT
    759                        IntegerIterator iter = new IntegerIterator(index, size);
    760
    761                        while (iter.hasNext()) {
    762                                data[iter.index] = dv;
    763                        }
    764                }
    765                return this;
    766        }
    767
    768        @Override
    769        public StringDatasetBase setByIndexes(final Object obj, final Object... indexes) {
    770                setDirty();
    771                final IntegersIterator iter = new IntegersIterator(shape, indexes);
    772                final int[] pos = iter.getPos();
    773
    774                if (obj instanceof Dataset) {
    775                        final Dataset ds = (Dataset) obj;
    776                        if (ShapeUtils.calcSize(iter.getShape()) != ds.getSize()) {
    777                                throw new IllegalArgumentException(
    778                                                "Number of items in index datasets does not match number of items in dataset");
    779                        }
    780
    781                        final IndexIterator oiter = ds.getIterator();
    782
    783                        while (iter.hasNext() && oiter.hasNext()) {
    784                                setItem(ds.getStringAbs(oiter.index), pos); // GET_ELEMENT_WITH_CAST
    785                        }
    786                } else {
    787                        final String dv = obj.toString(); // PRIM_TYPE // FROM_OBJECT
    788
    789                        while (iter.hasNext()) {
    790                                setItem(dv, pos);
    791                        }
    792                }
    793                return this;
    794        }
    795
    796        @Override
    797        StringDatasetBase setSlicedView(Dataset view, Dataset d) {
    798                setDirty();
    799                final BroadcastSelfIterator it = BroadcastSelfIterator.createIterator(view, d);
    800
    801                while (it.hasNext()) {
    802                        data[it.aIndex] = d.getStringAbs(it.bIndex);
    803                }
    804                return this;
    805        }
    806
    807        @Override
    808        public StringDatasetBase setSlice(final Object obj, final IndexIterator siter) {
    809                setDirty();
    810
    811                if (obj instanceof IDataset) {
    812                        final IDataset ds = (IDataset) obj;
    813                        final int[] oshape = ds.getShape();
    814
    815                        if (!ShapeUtils.areShapesCompatible(siter.getShape(), oshape)) {
    816                                throw new IllegalArgumentException(String.format(
    817                                                "Input dataset is not compatible with slice: %s cf %s", Arrays.toString(oshape),
    818                                                Arrays.toString(siter.getShape())));
    819                        }
    820
    821                        if (ds instanceof Dataset) {
    822                                final Dataset ads = (Dataset) ds;
    823                                final IndexIterator oiter = ads.getIterator();
    824
    825                                while (siter.hasNext() && oiter.hasNext())
    826                                        data[siter.index] = ads.getStringAbs(oiter.index); // GET_ELEMENT_WITH_CAST
    827                        } else {
    828                                final IndexIterator oiter = new PositionIterator(oshape);
    829                                final int[] pos = oiter.getPos();
    830
    831                                while (siter.hasNext() && oiter.hasNext())
    832                                        data[siter.index] = ds.getString(pos); // PRIM_TYPE
    833                        }
    834                } else {
    835                        try {
    836                                String v = obj.toString(); // PRIM_TYPE // FROM_OBJECT
    837
    838                                while (siter.hasNext())
    839                                        data[siter.index] = v;
    840                        } catch (IllegalArgumentException e) {
    841                                throw new IllegalArgumentException("Object for setting slice is not a dataset or number");
    842                        }
    843                }
    844                return this;
    845        }
    846
    847        @Override
    848        public void copyItemsFromAxes(final int[] pos, final boolean[] axes, final Dataset dest) {
    849                String[] ddata = (String[]) dest.getBuffer(); // PRIM_TYPE
    850
    851                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
    852                int[] sshape = ShapeUtils.squeezeShape(siter.getShape(), false);
    853
    854                IndexIterator diter = dest.getSliceIterator(null, sshape, null);
    855
    856                if (ddata.length < ShapeUtils.calcSize(sshape)) {
    857                        throw new IllegalArgumentException("destination array is not large enough");
    858                }
    859
    860                dest.setDirty();
    861                while (siter.hasNext() && diter.hasNext()) {
    862                        ddata[diter.index] = data[siter.index];
    863                }
    864        }
    865
    866        @Override
    867        public void setItemsOnAxes(final int[] pos, final boolean[] axes, final Object src) {
    868                setDirty();
    869                String[] sdata = (String[]) src; // PRIM_TYPE
    870
    871                SliceIterator siter = getSliceIteratorFromAxes(pos, axes);
    872
    873                if (sdata.length < ShapeUtils.calcSize(siter.getShape())) {
    874                        throw new IllegalArgumentException("destination array is not large enough");
    875                }
    876
    877                for (int i = 0; siter.hasNext(); i++) {
    878                        data[siter.index] = sdata[i];
    879                }
    880        }
    881
    882        private List<int[]> findPositions(final String value) { // PRIM_TYPE
    883                IndexIterator iter = getIterator(true);
    884                List<int[]> posns = new ArrayList<int[]>();
    885                int[] pos = iter.getPos();
    886
    887                {
    888                        while (iter.hasNext()) {
    889                                if (data[iter.index] == value) {
    890                                        posns.add(pos.clone());
    891                                }
    892                        }
    893                }
    894                return posns;
    895        }
    896
    897        @Override
    898        public int[] maxPos(boolean... ignoreInvalids) {
    899                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
    900                StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
    901                List<int[]> max = md.getMaximumPositions(ignoreInvalids);
    902
    903                if (max == null) {
    904                        // max = findPositions(md.getMaximum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
    905                        max = findPositions(md.getMaximum(ignoreInvalids).toString()); // OBJECT_USE
    906
    907                        md.setMaximumPositions(max);
    908                }
    909
    910                return max.get(0); // first maximum
    911        }
    912
    913        @Override
    914        public int[] minPos(boolean... ignoreInvalids) {
    915                // StatisticsMetadata<Number> md = getStats(); // BOOLEAN_USE
    916                StatisticsMetadata<String> md = getStringStats(); // OBJECT_USE
    917                List<int[]> min = md.getMinimumPositions(ignoreInvalids);
    918
    919                if (min == null) {
    920                        // min = findPositions(md.getMinimum(ignoreInvalids).intValue() != 0); // BOOLEAN_USE
    921                        min = findPositions(md.getMinimum(ignoreInvalids).toString()); // OBJECT_USE
    922
    923                        md.setMinimumPositions(min);
    924                }
    925
    926                return min.get(0); // first minimum
    927        }
    928
    929        @Override
    930        public boolean containsNans() {
    931                return false;
    932        }
    933
    934        @Override
    935        public boolean containsInfs() {
    936                return false;
    937        }
    938
    939        @Override
    940        public boolean containsInvalidNumbers() {
    941                return false;
    942        }
    943
    944        @Override
    945        public StringDatasetBase iadd(final Object b) {
    946                return this;
    947        }
    948
    949        @Override
    950        public StringDatasetBase isubtract(final Object b) {
    951                return this;
    952        }
    953
    954        @Override
    955        public StringDatasetBase imultiply(final Object b) {
    956                return this;
    957        }
    958
    959        @Override
    960        public StringDatasetBase idivide(final Object b) {
    961                return this;
    962        }
    963
    964        @Override
    965        public StringDatasetBase ifloor() {
    966                return this;
    967        }
    968
    969        @Override
    970        public StringDatasetBase iremainder(final Object b) {
    971                return this;
    972        }
    973
    974        @Override
    975        public StringDatasetBase ipower(final Object b) {
    976                return this;
    977        }
    978
    979        @Override
    980        public double residual(final Object b, final Dataset w, boolean ignoreNaNs) {
    981                double sum = 0;
    982                return sum;
    983        }
    984}