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