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