inline VLXValue export_Sphere(const Sphere& sphere)
 {
   VLXValue value ( new VLXStructure("<vl::Sphere>") );
   *value.getStructure() << "Center" << vlx_toValue(sphere.center());
   *value.getStructure() << "Radius" << sphere.radius();
   return value;
 }
    bool readValue(VLXValue& val)
    {
      unsigned char chunk = 0;

      if (!readChunk(chunk))
        return false;

      std::string str;

      switch(chunk)
      {

      case VLB_ChunkStructure:
        val.setStructure( new VLXStructure );
        return parseStructure( val.getStructure() );
      
      case VLB_ChunkList:
        val.setList( new VLXList );
        return parseList( val.getList() );

      case VLB_ChunkArrayInteger:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayInteger( new VLXArrayInteger( str.c_str() ) );

          // count
          long long count = 0;
          if (!readInteger(count))
            return false;

          // values
          VLXArrayInteger& arr = *val.getArrayInteger();
          if (count)
          {
            long long encode_count = 0;
            if (!readInteger(encode_count))
              return false;
            VL_CHECK(encode_count >= 0)
            if (encode_count)
            {
              std::vector<unsigned char> encoded;
              encoded.resize((size_t)encode_count);
              inputFile()->readUInt8(&encoded[0], encode_count);
              decodeIntegers(encoded, arr.value());
            }
          }
          VL_CHECK((size_t)count == arr.value().size())
          return (size_t)count == arr.value().size();
        }

      case VLB_ChunkArrayRealDouble:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayReal( new VLXArrayReal( str.c_str() ) );
          // count
          long long count = 0;
          if (!readInteger(count))
            return false;
          // values
          VLXArrayReal& arr = *val.getArrayReal();
          arr.value().resize( (size_t)count );
          if (count)
          {
#if 1
            long long c = inputFile()->readDouble( &arr.value()[0], count );
            VL_CHECK(c == count * (int)sizeof(double))
            return c == count * (int)sizeof(double);
#elif 0
            long long zsize = 0;
            readInteger(zsize);
            std::vector<unsigned char> zipped;
            zipped.resize((size_t)zsize);
            inputFile()->read(&zipped[0], zipped.size());
            bool ok = decompress(&zipped[0], (size_t)zsize, &arr.value()[0]);
            VL_CHECK(ok);
            return ok;
#endif
          }
          else
            return true;
        }

      case VLB_ChunkArrayRealFloat:
        {
          // tag
          if (!readString(str))
            return false;
          else
            val.setArrayReal( new VLXArrayReal( str.c_str() ) );
          // count
          long long count = 0;
          if (!readInteger(count))
            return false;
          // values
          VLXArrayReal& arr = *val.getArrayReal();
          arr.value().resize( (size_t)count );
          if (count)
          {
#if 1
            std::vector<float> floats;
            floats.resize( (size_t)count );
            long long c = inputFile()->readFloat( &floats[0], count );
            // copy over floats to doubles
            for(size_t i=0; i<floats.size(); ++i)
              arr.value()[i] = floats[i];
            VL_CHECK(c == count * (int)sizeof(float))
            return c == count * (int)sizeof(float);
#elif 0
            long long zsize = 0;
            readInteger(zsize);
            std::vector<unsigned char> zipped;
            zipped.resize((size_t)zsize);
            inputFile()->read(&zipped[0], zipped.size());
            bool ok = decompress(&zipped[0], (size_t)zsize, &arr.value()[0]);
            VL_CHECK(ok);
            return ok;
#endif
          }
          else
            return true;
        }