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