text: #pragma once
  
  #include <DataTypes/Serializations/SimpleTextSerialization.h>
  
  namespace DB
  {
  
  class SerializationArray final : public SimpleTextSerialization
  {
  private:
      SerializationPtr nested;
  
  public:
      SerializationArray(const SerializationPtr & nested_) : nested(nested_) {}
  
      void serializeBinary(const Field & field, WriteBuffer & ostr) const override;
      void deserializeBinary(Field & field, ReadBuffer & istr) const override;
      void serializeBinary(const IColumn & column, size_t row_num, WriteBuffer & ostr) const override;
      void deserializeBinary(IColumn & column, ReadBuffer & istr) const override;
  
      void serializeText(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings &) const override;
      void deserializeText(IColumn & column, ReadBuffer & istr, const FormatSettings &, bool whole) const override;
  
      void serializeTextJSON(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings &) const override;
      void deserializeTextJSON(IColumn & column, ReadBuffer & istr, const FormatSettings &) const override;
  
      void serializeTextXML(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings &) const override;
  
      void serializeTextCSV(const IColumn & column, size_t row_num, WriteBuffer & ostr, const FormatSettings &) const override;
      void deserializeTextCSV(IColumn & column, ReadBuffer & istr, const FormatSettings &) const override;
  
      /** Streaming serialization of arrays is arranged in a special way:
        * - elements placed in a row are written/read without array sizes;
        * - the sizes are written/read in a separate stream,
        * This is necessary, because when implementing nested structures, several arrays can have common sizes.
        */
  
      void enumerateStreams(
          SubstreamPath & path,
          const StreamCallback & callback,
          const SubstreamData & data) const override;
  
      void serializeBinaryBulkStatePrefix(
              SerializeBinaryBulkSettings & settings,
              SerializeBinaryBulkStatePtr & state) const override;
  
      void serializeBinaryBulkStateSuffix(
              SerializeBinaryBulkSettings & settings,
              SerializeBinaryBulkStatePtr & state) const override;
  
      void deserializeBinaryBulkStatePrefix(
              DeserializeBinaryBulkSettings & settings,
              DeserializeBinaryBulkStatePtr & state) const override;
  
      void serializeBinaryBulkWithMultipleStreams(
              const IColumn & column,
              size_t offset,
              size_t limit,
              SerializeBinaryBulkSettings & settings,
              SerializeBinaryBulkStatePtr & state) const override;
  
      void deserializeBinaryBulkWithMultipleStreams(
          ColumnPtr & column,
          size_t limit,
          DeserializeBinaryBulkSettings & settings,
          DeserializeBinaryBulkStatePtr & state,
          SubstreamsCache * cache) const override;
  
  private:
      struct SubcolumnCreator : public ISubcolumnCreator
      {
          const ColumnPtr offsets;
  
          SubcolumnCreator(const ColumnPtr & offsets_) : offsets(offsets_) {}
  
          DataTypePtr create(const DataTypePtr & prev) const override;
          SerializationPtr create(const SerializationPtr & prev) const override;
          ColumnPtr create(const ColumnPtr & prev) const override;
      };
  };
  
  ColumnPtr arrayOffsetsToSizes(const IColumn & column);
  
  }
  