From 136832a96feb8d61b2275abebc7cf0354a7e5d24 Mon Sep 17 00:00:00 2001
From: Arnaud Blanchard <arnaud.blanchard@ensea.fr>
Date: Mon, 9 Nov 2020 18:42:51 +0100
Subject: [PATCH] new version of blc based on C++14 and minimime cmake 3.13

---
 CMakeLists.txt                                |  57 ++++++--
 blc-config.cmake                              |  20 ---
 include/blc.h                                 |  12 ++
 include/blc_array.h                           |  43 +++---
 include/blc_array_tcp4_client.h               |  37 +++--
 include/blc_array_tcp4_server.h               |  22 +--
 include/blc_channel.h                         |  17 +--
 include/blc_image.h                           |  12 ++
 python/blc_array.py                           |  64 ++++++---
 python/blc_network.py                         | 132 ++++++++++++------
 src/channel/blc_channel.cpp                   |  36 ++---
 src/channel/channel_file.cpp                  |  57 +++-----
 src/core/blc_array.cpp                        |  95 ++++++++-----
 src/image/blc_image.cpp                       |  33 +++--
 src/network/blc_array_tcp4_client.cpp         |  59 ++++++--
 src/network/blc_array_tcp4_server.cpp         |  51 +++++--
 src/network/blc_network.cpp                   |   3 +-
 test/network/CMakeLists.txt                   |  22 +++
 test/t_array_tcp4_client/CMakeLists.txt       |   8 ++
 .../t_array_tcp4_client.cpp                   |  16 +++
 test/t_array_tcp4_server/CMakeLists.txt       |   9 ++
 .../t_array_tcp4_server.cpp                   |  17 +++
 22 files changed, 542 insertions(+), 280 deletions(-)
 delete mode 100644 blc-config.cmake
 create mode 100644 include/blc.h
 create mode 100644 test/network/CMakeLists.txt
 create mode 100644 test/t_array_tcp4_client/CMakeLists.txt
 create mode 100644 test/t_array_tcp4_client/t_array_tcp4_client.cpp
 create mode 100644 test/t_array_tcp4_server/CMakeLists.txt
 create mode 100644 test/t_array_tcp4_server/t_array_tcp4_server.cpp

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1744f78..ab60ff3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,27 +1,56 @@
 # Set the minimum version of cmake required to build this project
-cmake_minimum_required(VERSION 2.6)
-project(blc)
+cmake_minimum_required(VERSION 3.13) #Common version of raspbian
+project(blc VERSION 1 )
 
-set (sources
+find_package(JPEG)
+find_package(PNG)
+
+add_library(objlib OBJECT
     src/channel/blc_channel.cpp   src/channel/channel_file.cpp
     src/core/blc_array.cpp  src/core/blc_mem.cpp  src/core/blc_realtime.cpp  src/core/blc_text.cpp  src/core/blc_tools.cpp
     src/image/blc_image.cpp  src/image/jpeg_tools.cpp
-    src/network/blc_array_tcp4_client.cpp   src/network/blc_array_tcp4_server.cpp   src/network/blc_network.cpp   src/network/blc_server.cpp
+    src/network/blc_array_tcp4_client.cpp   src/network/blc_array_tcp4_server.cpp   src/network/blc_network.cpp
     src/process/blc_process.cpp
     src/program/blc_command.cpp   src/program/blc_loop.cpp   src/program/blc_program.cpp
-    )
+)
+
+add_library(blc SHARED $<TARGET_OBJECTS:objlib>)
+add_library(static_blc STATIC $<TARGET_OBJECTS:objlib>)
+
+target_compile_features(objlib PRIVATE cxx_std_14)
+target_include_directories(objlib PUBLIC
+    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
+    $<INSTALL_INTERFACE:include>
+)
+
+if (JPEG_FOUND)
+target_include_directories(objlib PRIVATE ${JPEG_INCLUDE_DIRS})
+target_link_libraries(blc PRIVATE ${JPEG_LIBRARY})
+else()
+message("Without libjpeg")
+target_compile_definitions(blc PRIVATE -DWITHOUT_JPEG)
+endif()
 
-add_definitions(-std=c++14  -Wno-multichar)
-include_directories(include)
 
-add_library(blc SHARED ${sources})
-add_library(static_blc STATIC ${sources})
 #Both version of librairies will have the same name only the extension will change.
 set_target_properties(static_blc PROPERTIES OUTPUT_NAME blc)
-	
+
 #Describe what will have to be installed or in the package by default the prefix (CMAKE_INSTALL_PREFIX) is '/usr/’ or '/usr/local' depending on your system
-install(DIRECTORY include/ DESTINATION include/blc)
-install(TARGETS blc static_blc DESTINATION lib)
-install(FILES  ${PROJECT_SOURCE_DIR}/blc-config.cmake   DESTINATION share/blc)
+install(TARGETS blc static_blc
+    EXPORT blc-config
+   # PUBLIC_HEADER DESTINATION include/blc
+
+    INCLUDES DESTINATION include/blc
+)
+#    EXPORT blc-config
+#    INCLUDES DESTINATION include/blc)
+install(DIRECTORY  include/ DESTINATION include/blc)
+install(DIRECTORY  python/ DESTINATION lib/blc_python)
+
+install(EXPORT blc-config  DESTINATION share/blc )
+
+#DIRECTORY include/ DESTINATION include/blc)
+#install(TARGETS blc static_blc DESTINATION lib)
+#install(FILES  ${PROJECT_SOURCE_DIR}/blc-config.cmake   DESTINATION share/blc)
 #Wrapping for python
-install(DIRECTORY  ${PROJECT_SOURCE_DIR}/python/   DESTINATION lib/blc_python)
+#install(DIRECTORY  ${PROJECT_SOURCE_DIR}/python/   DESTINATION lib/blc_python)
diff --git a/blc-config.cmake b/blc-config.cmake
deleted file mode 100644
index bb1802c..0000000
--- a/blc-config.cmake
+++ /dev/null
@@ -1,20 +0,0 @@
-# - Try to find blc_core used by find_package()
-# Once done this will define
-#  BLC_FOUND - System has blc_core
-#  BL_INCLUDE_DIRS - The blc_core include directories
-#  BL_LIBRARIES - The libraries needed to use blc_core
-#  BL_DEFINITIONS - Compiler switches required for using blc_core
-
-find_path(BLC_INCLUDE_DIR blc.h PATH_SUFFIXES blc )
-find_library(BLC_LIBRARY blc)
-
-include(FindPackageHandleStandardArgs)
-# handle the QUIETLY and REQUIRED arguments and set _FOUND to TRUE
-# if all listed variables are TRUE
-find_package_handle_standard_args(blc DEFAULT_MSG BLC_LIBRARY BLC_INCLUDE_DIR)
-
-mark_as_advanced(BLC_INCLUDE_DIR BLC_LIBRARY )
-
-set(BL_DEFINITIONS -Wno-multichar ${BL_DEFINITIONS})
-set(BL_INCLUDE_DIRS ${BLC_INCLUDE_DIR} ${BL_INCLUDE_DIRS} )
-set(BL_LIBRARIES ${BLC_LIBRARY} ${BL_LIBRARIES})	
diff --git a/include/blc.h b/include/blc.h
new file mode 100644
index 0000000..61079b7
--- /dev/null
+++ b/include/blc.h
@@ -0,0 +1,12 @@
+#ifndef BLC_H
+#define BLC_H
+
+
+#include "blc_channel.h"
+#include "blc_core.h"
+#include "blc_image.h"
+#include "blc_network.h"
+#include "blc_process.h"
+#include "blc_program.h"
+
+#endif
diff --git a/include/blc_array.h b/include/blc_array.h
index cd97fd4..55b2a44 100644
--- a/include/blc_array.h
+++ b/include/blc_array.h
@@ -20,6 +20,9 @@
 #include "blc_tools.h"
 #include "blc_mem.h"
 
+#ifdef __cplusplus
+#include <vector>
+#endif
 /**
  @defgroup blc_array blc_array
  @{
@@ -35,11 +38,8 @@ typedef struct blc_dim {
     size_t step; ///< shift in bytes to do to pass from one element of this dimension to the next one
 } blc_dim;
 
-START_EXTERN_C
-blc_dim *vcreate_blc_dims(size_t *size, uint32_t type, int dims_nb, int length, va_list arguments);
 
-blc_dim *create_blc_dims(size_t *size, uint32_t type, int dims_nb, int length0, ...);
-END_EXTERN_C
+blc_dim *create_blc_dims(size_t *size, uint32_t type, std::vector<size_t> const &lengths);
 
 ///Description of a n-dimensional array with type and format
 typedef struct blc_array
@@ -49,7 +49,7 @@ typedef struct blc_array
     /**Define an empty array*/
     blc_array();
     /**Define and allocates the array */
-    blc_array(uint32_t type, uint32_t format, int dims_nb, int length0, ...);
+    blc_array(uint32_t type, uint32_t format, std::vector<size_t> const &lengths);
     
     /**Copy the definition of the array, NOT the content  */
     blc_array(blc_array const &array);
@@ -66,25 +66,12 @@ typedef struct blc_array
  ====================================================================================*/
     
     /**Defines the blc_array but does not allocate memory (data)*/
-    void vdef_array(uint32_t type, uint32_t format, int dims_nb, int length0, va_list arguments);
-    /**Defines the blc_array but does not allocate memory (data)*/
-    void def_array(uint32_t type, uint32_t format, int dims_nb, int length0, ...);
+    void def_array(uint32_t type, uint32_t format, std::vector<size_t> const &lengths);
     /**Defines the blc_array but does not allocate memory (data)*/
     void def_array(uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims);
     /**Defines the blc_array but does not allocate memory (data)*/
     void def_array(uint32_t type, uint32_t format, char const *dims_string);
     
-    
-/* Allocating the array
- ====================*/
-    
-    /**Defines and allocates the blc_array with a string (i.e. "UIN8 RGB3 3x800x600")*/
-    void init(char const *properties);
-    /**Defines and allocates the blc_array */
-    void vinit(uint32_t type, uint32_t format, int dims_nb, int length, va_list arguments);
-    /**Defines and allocates the blc_array */
-    void init(uint32_t type, uint32_t format, int dims_nb, int length0, ...);
-    
 /* Printing informations about the blc_array
 ==========================================*/
     
@@ -103,11 +90,11 @@ typedef struct blc_array
 ======================================*/
 
     /**Add one dimention to the definition of the blc_array. You have to  manage  eventual **memory reallocation** yourself.*/
-    void add_dim(int length, int step);
+    void add_dim(size_t length, size_t step);
     /**Add one dimension ti the definition of the blc_array. The step is infered from the type of the data and the size of the previous dimension. You have to manage the eventual **memory reallocation** yourself.*/
-    void add_dim(int length);
+    void add_dim(size_t length);
     /** Set all the dims of the array*/
-    void set_dims(int dims_nb, int length, ...);
+    void set_dims(int dims_nb, size_t length0, ...); //Should use vector<size_t> instead of ...
     /**Set all dims by reading the properties from the string  (i.e. "3x800x600" ).  You have to  manage  eventual **memory reallocation** yourself. */
     int sscan_dims(char const* string);
     /**Set all dims by reading the properties from the file  (i.e. "3x800x600" ).  You have to  manage  eventual **memory reallocation** yourself. */
@@ -167,16 +154,22 @@ typedef struct blc_array
     START_EXTERN_C
     /** Useful for binding with python*/
      blc_array *blc_array_new_void();
-     blc_array *blc_array_new( uint32_t type, uint32_t format, int dims_nb, int length0, ...);    
+     blc_array *blc_array_new( uint32_t type, uint32_t format, int dims_nb, size_t length0, ...);
     /** Useful for binding with python */
     void blc_array_delete(blc_array *array);
     ///Returns a pointer to data
     void *blc_array_get_data(blc_array *array);
+    
+    uint32_t blc_array_get_type(blc_array *array);
+    uint32_t blc_array_get_format(blc_array *array);
+    int blc_array_get_dims_nb(blc_array *array);
+    blc_dim *blc_array_get_dims(blc_array *array);
+    int blc_array_get_total_length(blc_array *array);
 
     /**Define but does not allocate the blc_array.*/
-    void blc_array_def(blc_array *blc_array,  uint32_t type, uint32_t format, int dims_nb, int length0, ...);
+    void blc_array_def(blc_array *blc_array,  uint32_t type, uint32_t format, int dims_nb, size_t length0, ...);
     /**Define and allocate the blc_array*/
-    void blc_array_init(blc_array *blc_array,  uint32_t type, uint32_t format, int dims_nb, int length0, ...);
+    void blc_array_init(blc_array *blc_array,  uint32_t type, uint32_t format, int dims_nb, size_t length0, ...);
     /** like blc_fatal_error but add informations about the blc_array.  You should not call it, it is called by EXIT_ON_ARRAY_ERROR*/
     void blc_array_fatal_error(blc_array const *array, const char *name_of_file, const char* name_of_function, int numero_of_line, const char *message, ...);
     /**Free the dims description and data if not null of the array*/
diff --git a/include/blc_array_tcp4_client.h b/include/blc_array_tcp4_client.h
index 3b7cfa2..f658a24 100644
--- a/include/blc_array_tcp4_client.h
+++ b/include/blc_array_tcp4_client.h
@@ -1,26 +1,43 @@
-#ifndef BLC_ARRAY_TCP4_CLIENT_HPP
-#define BLC_ARRAY_TCP4_CLIENT_HPP
+#ifndef BLC_ARRAY_TCP4_CLIENT_H
+#define BLC_ARRAY_TCP4_CLIENT_H
 
 #include"blc_core.h"
+
+#ifdef __cplusplus
 #include <string>
+#include <vector>
+#endif
+
+typedef struct blc_array_tcp4_client
+#ifdef __cplusplus
+:blc_array {
+    blc_array_tcp4_client(std::string const &address, std::string const &port_name);
+    blc_array_tcp4_client(std::string const &address, std::string const &port_name, uint32_t type, uint32_t format, std::vector<size_t> const &lengths);
 
-typedef struct blc_array_tcp4_client{
-    blc_array_tcp4_client(blc_array  *array, std::string const &address,  std::string const &port_name);
     ~blc_array_tcp4_client();
 
+    
     void read_properties();
-    void server_manager();
-    void read_data();
+ //   void server_manager();
+    int recv_data();
+    int bytes_to_read();
     void send_data();
-
-    blc_array  *array;
+#else
+{   blc_array array;// Not beautiful but makes it easy to convert C++ heritage of "class"  in C struct inclusion.
+#endif
     int socket_fd;
 }blc_array_tcp4_client;
 
 START_EXTERN_C
-blc_array_tcp4_client *blc_array_tcp4_client_new(blc_array *array, const char *address, const char* port);
+blc_array_tcp4_client *blc_array_tcp4_client_new_void(const char *address, const char* port);
+    blc_array_tcp4_client *blc_array_tcp4_client_new( char const *address, char const *port_name, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...);
+
+void blc_array_tcp4_client_send_data(blc_array_tcp4_client *client);
+int blc_array_tcp4_client_recv_data(blc_array_tcp4_client *client);
+int blc_array_tcp4_client_bytes_to_read(blc_array_tcp4_client *client);
+
 void blc_array_tcp4_client_delete(blc_array_tcp4_client *client);
 END_EXTERN_C
 
 
-#endif // BLC_ARRAY_TCP4_CLIENT_HPP
+#endif // BLC_ARRAY_TCP4_CLIENT_H
diff --git a/include/blc_array_tcp4_server.h b/include/blc_array_tcp4_server.h
index c915f69..5a444ff 100644
--- a/include/blc_array_tcp4_server.h
+++ b/include/blc_array_tcp4_server.h
@@ -5,33 +5,35 @@
 #include <string>
 #include <thread>
 
-typedef struct blc_array_tcp4_server{
+typedef struct blc_array_tcp4_server
 #ifdef __cplusplus
-    blc_array_tcp4_server(blc_array  *array, std::string const &port_name);
+:blc_array {
+    blc_array_tcp4_server(std::string const &port_name);
+    blc_array_tcp4_server(std::string const &port_name, uint32_t type, uint32_t format, std::vector<size_t> const &lengths);
+
     ~blc_array_tcp4_server();
 
     void send_properties();
     void server_manager();
-    int read_data();
+    int recv_data();
     int send_data();
+    int bytes_to_send();
     int wait_connection();
-#endif
-
+#else
     blc_array  *array;
+#endif
     int socket_fd, client_socket=-1; //We suppose only on client
 }blc_array_tcp4_server;
 
 START_EXTERN_C
-blc_array_tcp4_server *blc_array_tcp4_server_new(blc_array *array, char const*port_name);
+blc_array_tcp4_server *blc_array_tcp4_server_new_void(char const *port_name);
+blc_array_tcp4_server *blc_array_tcp4_server_new(char const *port_name, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...);
 int blc_array_tcp4_server_wait_connection(blc_array_tcp4_server *server);
 void blc_array_tcp4_server_delete(blc_array_tcp4_server *server);
 END_EXTERN_C
 
 /*
-void blc_array_tcp4_server_thread(blc_array *array, string const &port_name){
-
+    void blc_array_tcp4_server_thread(blc_array *array, string const &port_name){
 }*/
 
-
-
 #endif // BLC_ARRAY_TCP4_SERVER_HPP
diff --git a/include/blc_channel.h b/include/blc_channel.h
index f4f33bf..7307a98 100644
--- a/include/blc_channel.h
+++ b/include/blc_channel.h
@@ -66,11 +66,10 @@ typedef struct blc_channel
     ///Constructor opening the blc_channel in reading mode by default (otherwise use BLC_CHANNEL_WRITE)
     blc_channel(char const *new_name, int mode);
     ///Constructor creating or opening the channel if it exist. In this case it has to be compatible with its properties.
-    blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, int length, va_list vargs);
+    blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, std::vector<size_t> lengths);
     ///Constructor creating or opening the channel if it exist. In this case it has to be compatible with its properties.
     blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims);
-
-    blc_channel(char const *name, int mode,  uint32_t type, uint32_t format, int dims_nb, int length0, ...);
+    
     
     //Warning copying channel with data, the new data is not mapped anymore
     blc_channel(blc_channel const &channel);
@@ -110,13 +109,13 @@ typedef struct blc_channel
     /**Create a new blc_channel with the already defined arguments*/
     void create(int mode);
     /**Create a new blc_channel with the list of dims described as va_args*/
-    void vcreate(char const *name, int mode, uint32_t type, uint32_t format, int dims_nb, size_t length0, va_list arguments);
+//   void vcreate(char const *name, int mode, uint32_t type, uint32_t format, int dims_nb, size_t length0, va_list arguments);
     /**Create a new blc_channel with the list of dims described as va_args*/
-    int vcreate_or_open(char const *name, int mode, uint32_t type, uint32_t format, int dims_nb, size_t length0, va_list arguments);
+//    int vcreate_or_open(char const *name, int mode, uint32_t type, uint32_t format, int dims_nb, size_t length0, va_list arguments);
     /**Creates a new blc_channel with the properties already defined*/
     void create(char const *new_name, int mode);
     /**Creates a new blc_channel and with the dims as a variable list of arguments */
-    void create(char const *new_name, int mode, uint32_t  type, uint32_t format, int dims_nb, size_t length0, ...);
+    void create(char const *new_name, int mode, uint32_t  type, uint32_t format, std::vector<size_t> lengths);
     /**Creates a new blc_channel and with the dims as an array of dims*/
     void create(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims);
     /**Creates a new blc_channel and with the dims as a string (i.e. "3x800x600") */
@@ -129,7 +128,7 @@ typedef struct blc_channel
      You can use conflict function to check before if there is incompatibility.
      Return 1 if it has been created*/
     int create_or_open(char const *new_name, int mode);
-    int create_or_open(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...);
+    int create_or_open(char const *new_name, int mode, uint32_t type, uint32_t format, std::vector<size_t>lengths);
     int create_or_open(char const *new_name, int mode, uint32_t type, uint32_t format,  int dims_nb, blc_dim const *dims);
     int create_or_open(char const *new_name, int mode, uint32_t type, uint32_t format, char const *size_string);
     
@@ -165,6 +164,8 @@ typedef struct blc_channel
         sem_t *sem_new_data, *sem_ack_data;
     }blc_channel;
     
+    
+    
     START_EXTERN_C
     
     /** Wait until new data is available
@@ -216,7 +217,7 @@ typedef struct blc_channel
     /**Open an exisiting channel 'name' */
     void blc_channel_open(blc_channel* channel, const char *name, int mode);
     /**Open an exisiting channel 'name' or create it if it does not exist */
-    int blc_channel_create_or_open(blc_channel *channel, const char *name, int mode,  uint32_t type, uint32_t format, int dims_nb, int length0, ...);
+    void blc_channel_create_or_open(blc_channel *channel, const char *name, int mode,  uint32_t type, uint32_t format, int dims_nb, int length0, ...);
     /** Close the channel and unlink the shared memory. No new process can use it.*/
     int blc_channel_remove(blc_channel *channel);
     /** Allocate (need to be free) and give the array of existing shared memory files on the system.*/
diff --git a/include/blc_image.h b/include/blc_image.h
index 6bed35c..5a69053 100644
--- a/include/blc_image.h
+++ b/include/blc_image.h
@@ -35,6 +35,18 @@ Specific functions to manipulate blc_array as images:
  @defgroup blc_image blc_image functions
  @{
  */
+#ifdef __cplusplus
+typedef struct blc_image:blc_array{
+    void convert(blc_array const &image);
+}blc_image;
+
+typedef struct blc_Y800_image:blc_array{
+    void convert(blc_array const &image);
+}blc_Y800_image;
+
+
+#endif
+
 
 START_EXTERN_C
 
diff --git a/python/blc_array.py b/python/blc_array.py
index 3881fdd..20ba3b2 100644
--- a/python/blc_array.py
+++ b/python/blc_array.py
@@ -4,7 +4,7 @@
 from ctypes import *
 from ctypes.util import find_library
 
-path=find_library("blc_core")
+path=find_library("blc")
 lib = CDLL(name=path)
 
 class BlcDim(Structure):
@@ -14,9 +14,20 @@ class BlcArray:
     lib.blc_array_new.restype = c_void_p
     lib.blc_array_new_void.restype = c_void_p
     lib.blc_array_new_void.argtypes = []
+    lib.blc_array_get_type.argtypes = [ c_void_p ]
+    lib.blc_array_get_type.restype = c_uint32
+    lib.blc_array_get_format.argtypes = [ c_void_p ]
+    lib.blc_array_get_format.restype = c_uint32
+    lib.blc_array_get_total_length.argtypes = [ c_void_p ]
+    lib.blc_array_get_total_length.restype = c_int
+    lib.blc_array_get_dims_nb.argtypes = [ c_void_p ]
+    lib.blc_array_get_dims_nb.restype = c_int
+    lib.blc_array_get_dims.argtypes = [ c_void_p ]
+    lib.blc_array_get_data.argtypes = [ c_void_p ]
+    lib.blc_array_get_data.restype = c_void_p
 
     lib.blc_array_delete.argtypes = [ c_void_p ]
-    types={ 'UIN8': c_uint8, 'INT8': c_int8, 'UI16': c_uint16, 'INT16': c_int16, 'UI32': c_uint32, 'IN32': c_int32, 'UI64': c_uint64, 'IN64': c_int64, 'FL32': c_float, 'FL64': c_double}
+    types={ 'UIN8': c_uint8, 'INT8': c_int8, 'UI16': c_uint16, 'IN16': c_int16, 'UI32': c_uint32, 'IN32': c_int32, 'UI64': c_uint64, 'IN64': c_int64, 'FL32': c_float, 'FL64': c_double}
 
     def __init__(self,  data_type=None, format_type=None, dims=None):
         self.type = data_type
@@ -24,38 +35,51 @@ class BlcArray:
         self.dims = dims
         
         if (dims): #Creates
-            dim_types = [c_int] * len(dims)
-            lib.blc_array_new.argtypes = [c_uint32, c_uint32, c_int, c_int, c_int ]
+            dim_types = [c_size_t] * len(dims)
+            lib.blc_array_new.argtypes = [c_uint32, c_uint32, c_int, *dim_types ]
             
             # Create a new array
-            self.pointer = lib.blc_array_new(int.from_bytes(data_type.encode(), "big"), int.from_bytes(format_type.encode(), "big"), 2, 64, 4)
+            self.pointer = lib.blc_array_new(int.from_bytes(data_type.encode(), "big"), int.from_bytes(format_type.encode(), "big"), len(dims), *dims)
         
-            #Compute the length of the array
-            self.total_length=1
-            for length in dims:
-                self.total_length *= length
+            total_length = lib.blc_array_get_total_length(self.pointer)
         
-            # Specify types for channel
+            # Specify types for array
             self.ctype = BlcArray.types[self.type]
+            
             # Specify pointer of data for array
-            self.data = cast(lib.blc_array_get_data(self.pointer), POINTER(self.ctype))
+            self.data = cast(lib.blc_array_get_data(self.pointer), POINTER(self.ctype*total_length)).contents
         else:
             self.pointer = lib.blc_array_new_void()
+           # lib.blc_array_get_dims.restype = POINTER(BlcDim  * dims_nb)
+           # blc_dims=BlcChannel.lib.blc_channel_get_dims(self.channel)
+           # self.dims=[]
+           # for i in range(self.dims_nb):
+           #     self.dims.append(blc_dims[0][i].length)
+           
+    def get_def(self):   
+        self.type=lib.blc_array_get_type(self.pointer).to_bytes(4, "big").decode()
+        self.ctype = BlcArray.types[self.type]
+        self.format=lib.blc_array_get_format(self.pointer).to_bytes(4, "big").decode()
         
+        dims_nb=lib.blc_array_get_dims_nb(self.pointer)
+        lib.blc_array_get_dims.restype = POINTER(BlcDim  * dims_nb)
+        blc_dims=lib.blc_array_get_dims(self.pointer)
+        self.dims=[]
+        for i in range(dims_nb):
+            self.dims.append(blc_dims[0][i].length)
+            
+        total_length = lib.blc_array_get_total_length(self.pointer)
+        self.data = cast(lib.blc_array_get_data(self.pointer), POINTER(self.ctype*total_length)).contents
         
     def __del__(self):
-        BlcArray.lib.blc_array_delete(self.array)
+        lib.blc_array_delete(self.pointer)
 
 if __name__ == "__main__":
     
     undef_array = BlcArray()
-    array = BlcArray('UIN8', 'TEXT', [16, 2])
-    
-    array.data[0]=32
-    array.data[1]=8
-    array.data[2]=0
-
+    array = BlcArray('UIN8', 'TEXT', [16, 3])
+    array.get_def() #Useless here, only for testing the function
     
-    print("type",array.type, "format", array.format, "length", array.total_length)
-    print(array.data[:array.total_length])
+    print("type",array.type, "format", array.format, "length", len(array.data))
+  #  print(array.data[:array.total_length])
 
diff --git a/python/blc_network.py b/python/blc_network.py
index 9d3ebb5..c58ba1b 100644
--- a/python/blc_network.py
+++ b/python/blc_network.py
@@ -2,80 +2,130 @@
 from ctypes import *
 from ctypes.util import find_library
 
-from blpy_core import BlcArray
+from blc_array import BlcArray
 
-# Bind blc_network methods
-lib_path = find_library("blc_network")
+# Bind blc network methods
+lib_path = find_library("blc")
 lib = CDLL(lib_path)
 
-class BlcArrayTCP4Server:
+class BlcArrayTCP4Server(BlcArray):
+    lib.blc_array_tcp4_server_new_void.restype = c_void_p
+    lib.blc_array_tcp4_server_new_void.argtypes = [ c_char_p ]
     lib.blc_array_tcp4_server_new.restype = c_void_p
-    lib.blc_array_tcp4_server_new.argtypes = [ c_void_p, c_char_p ]
-    lib.blc_array_tcp4_server_delete.argtypes = [ c_void_p ]
 
-    def __init__(self, array, port):
-        self.array = array
+    lib.blc_array_tcp4_server_recv_data.argtypes = [ c_void_p ]
+    lib.blc_array_tcp4_server_send_data.argtypes = [ c_void_p ]
+    lib.blc_array_tcp4_server_wait_connection.argtypes = [ c_void_p ]
+    lib.blc_array_tcp4_server_wait_connection.restype = c_int 
+    lib.blc_array_tcp4_server_delete.argtypes = [ c_void_p ]
+        
+    def __init__(self, port, data_type=None, format_type=None, dims=None):
         self.port = port
-        self.pointer = lib.blc_array_tcp4_server_new(array.pointer, port.encode())
+        if (dims):
+            dim_types = [c_size_t] * len(dims)
+            lib.blc_array_tcp4_server_new.argtypes = [ c_char_p, c_uint32, c_uint32, c_int, *dim_types ]
+            self.pointer = lib.blc_array_tcp4_server_new(port.encode(), int.from_bytes(data_type.encode(), "big"), int.from_bytes(format_type.encode(), "big"), len(dims), *dims )
+        else:
+            self.pointer = lib.blc_array_tcp4_server_new_void(port.encode())
+        
+        self.get_def()
+        print(self.data[:])
+
+        
+    def send_data(self):
+        lib.blc_array_tcp4_server_send_data(self.pointer)
     
+    def recv_data(self):
+        lib.blc_array_tcp4_server_recv_data(self.pointer)
+        
     def wait_connection(self):
         error = lib.blc_array_tcp4_server_wait_connection(self.pointer)
         if (error != 0):
-            raise Exception('Error in accept:'+ error) 
+            raise Exception('Error in accept:'+ error)
+        self.get_def() # update the array definition with the c data
     
     def __del__(self):
         lib.blc_array_tcp4_server_delete(self.pointer)
 
-class BlcArrayTCP4Client:
+class BlcArrayTCP4Client(BlcArray):
+    lib.blc_array_tcp4_client_new_void.restype = c_void_p
+    lib.blc_array_tcp4_client_new_void.argtypes = [ c_char_p, c_char_p ]
+    
     lib.blc_array_tcp4_client_new.restype = c_void_p
-    lib.blc_array_tcp4_client_new.argtypes = [ c_void_p, c_char_p, c_char_p ]
+
+    lib.blc_array_tcp4_client_recv_data.argtypes = [ c_void_p ]
+    lib.blc_array_tcp4_client_recv_data.restype = c_int
+    
+    lib.blc_array_tcp4_client_bytes_to_read.argtypes = [ c_void_p ]
+    lib.blc_array_tcp4_client_bytes_to_read.restype = c_int
+
+    lib.blc_array_tcp4_client_send_data.argtypes = [ c_void_p ]
     lib.blc_array_tcp4_client_delete.argtypes = [ c_void_p ]
 
-    def __init__(self, array, address, port):
-        self.array = array
+    def __init__(self, address, port, data_type=None, format_type=None, dims=None):
+        self.address=address
         self.port = port
-        self.pointer = lib.blc_array_tcp4_client_new(array.pointer, address.encode(), port.encode())
+        
+        if dims:
+            dim_types = [c_size_t] * len(dims)
+            lib.blc_array_tcp4_client_new.argtypes = [ c_char_p, c_char_p, c_uint32, c_uint32, c_int, *dim_types ]
+            self.pointer = lib.blc_array_tcp4_client_new( address.encode(), port.encode(),  int.from_bytes(data_type.encode(), "big"), int.from_bytes(format_type.encode(), "big"), len(dims), *dims )
+        else:
+            self.pointer = lib.blc_array_tcp4_client_new_void(address.encode(), port.encode())
+        
+        self.get_def() #get def of the array from the c data
+        
+
+    
+    def send_data(self):
+        lib.blc_array_tcp4_client_send_data(self.pointer)
+    
+    def recv_data(self):
+        return lib.blc_array_tcp4_client_recv_data(self.pointer)
+    
+    def bytes_to_recv(self):
+        return lib.blc_array_tcp4_client_bytes_to_read(self.pointer)
     
     def __del__(self):
-        blc_array_tcp4_client_delete(self.pointer)
+        lib.blc_array_tcp4_client_delete(self.pointer)
    
                 
 if __name__ == "__main__":
     import threading
     
-    class ServerThread (threading.Thread):
-        def __init__(self, server):
-            threading.Thread.__init__(self)
-            self.server=server
-
-        def run(self):
-            print("Serveur has started, waiting for connection\n")
-            self.server.wait_connection()
-            print("Client connected")
-            self.server.send_data()
     
     '''
     This thread is only for example, it is supposed to be executed in another process ( the server )
     '''
-    serverArray = BlcArray('UIN8', 'TEXT', [5])
-    serverArray.data[2]=3
-    server = BlcArrayTCP4Server(serverArray, "31440")
-    thread=ServerThread(server)
-    print("Initilized thread")
+    '''Client part'''
+    class ServerThread (threading.Thread):
+        def run(self):
+            server = BlcArrayTCP4Server( "31440", 'UIN8', 'TEXT', [5])
+            print("server data:", server.data[:])
+
+            server.data[3]=7 #Change values to check if the data will be received
+            print("server data:", server.data[:])
+            print("Server has started, waiting for connection\n")
+            server.wait_connection()
+            print("Client connected")
+            server.send_data()
+    
+    print("Initialize server thread")
+    thread=ServerThread()
     thread.start()
-    print("Server started")
     
-        
-    '''Client part'''
-    clientArray = BlcArray()
-    client = BlcArrayTCP4Client(clientArray, "localhost", "31440")
-    print("type",clientArray.type, "format", clientArray.format, "length", clientArray.total_length)
 
-    print(clientArray.array[:clientArray.total_length])
-    client.read_data()
-    print(clientArray.array[:clientArray.total_length])
     
+    '''Client part'''
+    client = BlcArrayTCP4Client("localhost", "31440")
+    print("type", client.type, "format", client.format, "length", len(client.data))
+
+    print("Values before receiving the data")
+    print(client.data[:])
+    client.recv_data()
+    print("Values after receiving the data")
+    print(client.data[:])
     thread.join()
+    #On some IDEs the __del__ functions are not called which cause the socket not being stopped before one minute    
     
     
-    
\ No newline at end of file
diff --git a/src/channel/blc_channel.cpp b/src/channel/blc_channel.cpp
index d6f9ec4..033524b 100644
--- a/src/channel/blc_channel.cpp
+++ b/src/channel/blc_channel.cpp
@@ -22,7 +22,7 @@
 #include "blc_channel.h"
 
 #include <errno.h>
-#include <string.h>
+#include <string.h> 
 #include <unistd.h>
 #include <limits.h>
 #include <pthread.h>
@@ -55,16 +55,19 @@ blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t
     create_or_open(new_name, access_mode, type, format, dims_nb, dims);
 }
 
-blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, int length, va_list vargs):blc_channel(){
-    vcreate_or_open(new_name, mode, type,format, dims_nb, length, vargs);
+blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, vector<size_t> lengths ):blc_channel(){
+    blc_dim *dims=create_blc_dims(&size, type,  lengths);
+    create_or_open(new_name, mode, type,format, dims_nb, dims);
+    FREE(dims); //probably better to do in RAII
 }
-
+/*
 blc_channel::blc_channel(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, int length, ...):blc_channel(){
     va_list arguments;
     va_start(arguments, length);
     vcreate_or_open(new_name, mode, type,format, dims_nb, length, arguments);
     va_end(arguments);
 }
+ */
 
 blc_channel::blc_channel(blc_channel const &channel):blc_array(channel),id(channel.id), fd(channel.fd), sem_new_data(nullptr), sem_ack_data(nullptr) {
     STRCPY(name, channel.name);
@@ -304,11 +307,13 @@ void blc_channel::create(char const *new_name, int access_mode, uint32_t type, u
     create(new_name, access_mode);
 }
 
+/*
 ///Create a blc channel
 void blc_channel::vcreate(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, size_t length, va_list arguments){
     vdef_array(type, format, dims_nb, length, arguments);
     create(new_name,  mode);
 }
+ */
 
 void blc_channel::create(char const *new_name, int mode, uint32_t type, uint32_t format, const char *size_string){
     if (size_string==NULL) EXIT_ON_SYSTEM_ERROR("You cannot have null dimension");
@@ -316,12 +321,10 @@ void blc_channel::create(char const *new_name, int mode, uint32_t type, uint32_t
     create(new_name, mode);
 }
 
-void blc_channel::create(char const *new_name, int mode,  uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
-    va_list arguments;
+void blc_channel::create(char const *new_name, int mode,  uint32_t type, uint32_t format, vector<size_t> lengths){
     
-    va_start(arguments, length0);
-    vcreate(new_name, mode,  type, format, dims_nb, length0, arguments);
-    va_end(arguments);
+    dims=create_blc_dims(&size, type, lengths);
+    create(new_name, access_mode, type, format, dims_nb, dims);
 }
 
 int blc_channel::conflict(const char *new_name){
@@ -432,25 +435,14 @@ int blc_channel::create_or_open(char const *new_name, int access_mode, uint32_t
 }
 
 ///Create a blc channel
-int blc_channel::vcreate_or_open(char const *new_name, int access_mode, uint32_t type, uint32_t format, int dims_nb, size_t length0, va_list arguments){
+int blc_channel::create_or_open(char const *new_name, int access_mode, uint32_t type, uint32_t format, vector<size_t> lengths){
     blc_dim *dims;
     size_t size;
     
-    dims=vcreate_blc_dims(&size, type, dims_nb, length0, arguments);
+    dims=create_blc_dims(&size, type, lengths);
     return create_or_open(new_name, access_mode, type, format, dims_nb, dims);
 }
 
-int blc_channel::create_or_open(char const *new_name, int mode, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...)
-{
-    va_list arguments;
-    int created;
-    
-    va_start(arguments, length0);
-    created=vcreate_or_open(new_name, mode,  type, format,  dims_nb, length0, arguments);
-    va_end(arguments);
-    return created;
-}
-
 int blc_channel::create_or_open(char const *new_name, int mode, uint32_t type, uint32_t format, char const *dims_string){
     int  created=1;
     size_t length;
diff --git a/src/channel/channel_file.cpp b/src/channel/channel_file.cpp
index 7d99cee..e3ea91e 100644
--- a/src/channel/channel_file.cpp
+++ b/src/channel/channel_file.cpp
@@ -55,43 +55,24 @@ START_EXTERN_C
 // This is especially for binding to external langage (e.g. python)
 blc_channel *blc_channel_new(char const *name, int mode,  uint32_t type, uint32_t format, int dims_nb, int length0, ...){
     blc_channel* channel;
-    va_list vargs;
-    
-    if (type==0 && format==0 && dims_nb==0 && length0==0){ //We open a channel
-        channel = new  blc_channel(name,  mode);
-    }
-    else {
-        va_start(vargs, length0);
-        channel = new blc_channel(name,  mode,   type,  format,  dims_nb,  length0, vargs);
-        va_end(vargs);
-    }
-    return channel;
-}
-
-// This is especially for binding to external langage (e.g. python)
-// Delete the channel. This is different from destroy which deinits the channel but does not remove the memory.
-void blc_channel_delete(blc_channel *channel){    
-    delete channel;
-}
-
-void *blc_channel_get_data(blc_channel *channel){
-    return channel->data;
+    vector<size_t> lengths(dims_nb, length0);
+    va_list arguments;
+    va_start(arguments, length0);
+    for (int i=1; i<dims_nb; i++) lengths.push_back(va_arg(arguments, size_t));
+    va_end(arguments);
+    return new blc_channel(name,  mode,  type,  format, lengths);
 }
 
-uint32_t blc_channel_get_type(blc_channel *channel){
-    return channel->type;
+blc_channel *blc_channel_new_open(char const *name, int mode){
+    return new  blc_channel(name,  mode);
 }
 
-uint32_t blc_channel_get_format(blc_channel *channel){
-    return channel->format;
-}
 
-int blc_channel_get_dims_nb(blc_channel *channel){
-    return channel->dims_nb;
-}
 
-blc_dim *blc_channel_get_dims(blc_channel *channel){
-    return channel->dims;
+// This is especially for binding to external langage (e.g. python)
+// Delete the channel. This is different from destroy which deinits the channel but does not remove the memory.
+void blc_channel_delete(blc_channel *channel){    
+    delete channel;
 }
 
 void blc_remove_channel_with_name(char const *name){
@@ -157,27 +138,29 @@ void blc_channel_fatal_error(blc_channel *channel, const char *name_of_file, con
     exit(EXIT_FAILURE);
 }
 
-void blc_channel_create(blc_channel *channel, const char *name, int mode,  uint32_t type, uint32_t format, int dims_nb, int length0, ...)
+void blc_channel_init(blc_channel *channel, const char *name, int mode,  uint32_t type, uint32_t format, int dims_nb, int length0, ...)
 {
     va_list arguments;
+    vector<size_t> lengths(dims_nb, length0);
     
     va_start(arguments, length0);
-    channel->create(name, mode, type, format, dims_nb, length0, arguments);
+    for(int i=1; i<dims_nb; i++) lengths.push_back(va_arg(arguments, size_t));
     va_end(arguments);
+    new (channel)blc_channel(name, mode, type, format, lengths);
 }
 
 void blc_channel_open(blc_channel *channel, const char *name, int mode){
     channel->open(name, mode);
 }
 
-int blc_channel_create_or_open(blc_channel *channel, const char *name, int mode,  uint32_t type, uint32_t format, int dims_nb, int length0, ...){
+void blc_channel_create_or_open(blc_channel *channel, const char *name, int mode,  uint32_t type, uint32_t format, int dims_nb, int length0, ...){
     int created;
     va_list arguments;
-    
+    vector<size_t> lengths(dims_nb, length0);
     va_start(arguments, length0);
-    created=channel->vcreate_or_open(name, mode, type,  format, dims_nb, length0, arguments);
+    for (int i=1; i<dims_nb; i++) lengths.push_back(va_arg(arguments, size_t));
     va_end(arguments);
-    return created;
+    new (channel)blc_channel(name, mode, type,  format, lengths);
 }
 
 //Search for channel name whatever is start by /,: ,^ or .
diff --git a/src/core/blc_array.cpp b/src/core/blc_array.cpp
index 6659152..f88d5ec 100644
--- a/src/core/blc_array.cpp
+++ b/src/core/blc_array.cpp
@@ -22,23 +22,27 @@
 #include <signal.h> //raise
 #include <stdio.h> //fopen
 #include <algorithm> //copy
+#include <vector>
 
-START_EXTERN_C
-blc_dim *vcreate_blc_dims(size_t *size, uint32_t type, int dims_nb, int length, va_list arguments){
+
+using namespace std;
+
+blc_dim *create_blc_dims(size_t *size, uint32_t type, vector<size_t>  const &lengths){
     blc_dim *dim, *dims;
     
-    dims=MANY_ALLOCATIONS(dims_nb, blc_dim);
+    dims=MANY_ALLOCATIONS(lengths.size(), blc_dim);
     *size=blc_get_type_size(type);
-    
-    FOR_EACH(dim, dims, dims_nb){
+
+    dim=dims;
+    for (auto length:lengths){
         dim->step=*size;
         (*size)*=length;
         dim->length=length;
-        length=va_arg(arguments, int);
+        dim++;
     }
     return dims;
 }
-
+/*
 blc_dim *create_blc_dims(size_t *size, uint32_t type, int dims_nb, int length0, ...){
     blc_dim *dims;
     va_list arguments;
@@ -48,18 +52,13 @@ blc_dim *create_blc_dims(size_t *size, uint32_t type, int dims_nb, int length0,
     
     va_end(arguments);
     return dims;
-}
-END_EXTERN_C
+}*/
 
 blc_array::blc_array():type('NDEF'), format('NDEF'), dims(NULL), dims_nb(0), total_length(0){}
 
-blc_array::blc_array(uint32_t type, uint32_t format, int dims_nb, int length0, ...){
-    va_list arguments;
-    
-    va_start(arguments, length0);
-    vdef_array( type,  format,  dims_nb,  length0, arguments);
+blc_array::blc_array(uint32_t type, uint32_t format, vector<size_t> const &lengths){
+    def_array( type,  format, lengths);
     allocate();
-    va_end(arguments);
 }
 
 blc_array::blc_array(blc_array const &array):blc_mem(array), type(array.type), format(array.format), dims_nb(array.dims_nb), total_length(array.total_length){
@@ -92,24 +91,15 @@ blc_array::~blc_array(){
     if (dims) FREE(dims);
 }
 
-void blc_array::vdef_array(uint32_t type, uint32_t format, int dims_nb, int length, va_list arguments){
+void blc_array::def_array(uint32_t type, uint32_t format, vector<size_t> const &lengths){
     total_length=1;
-    this->dims_nb=dims_nb;
+    this->dims_nb=lengths.size();
     this->type=type;
     this->format=format;
-    dims=vcreate_blc_dims(&size, type, dims_nb, length, arguments);
+    dims=create_blc_dims(&size, type, lengths);
     total_length=size/get_type_size();
 }
 
-void blc_array::def_array(uint32_t type, uint32_t format, int dims_nb, int length, ...){
-    va_list arguments;
-    
-    va_start(arguments, length);
-    vdef_array(type, format, dims_nb, length, arguments);
-    va_end(arguments);
-    
-}
-
 void blc_array::def_array(uint32_t type, uint32_t format, int dims_nb, blc_dim const *dims){
     
     this->type=type;
@@ -130,11 +120,13 @@ void blc_array::def_array(uint32_t type, uint32_t format, char const *dims_strin
     sscan_dims(dims_string);
 }
 
+/*
 void blc_array::init(char const *properties){
     sscan_properties(properties);
     allocate();
 }
 
+
 void blc_array::vinit(uint32_t type, uint32_t format, int dims_nb, int length, va_list arguments){
     vdef_array(type, format, dims_nb, length, arguments);
     allocate();
@@ -148,8 +140,8 @@ void blc_array::init(uint32_t type, uint32_t format, int dims_nb, int length, ..
     va_end(arguments);
     
 }
-
-void blc_array::add_dim(int length, int step){
+*/
+void blc_array::add_dim(size_t length, size_t step){
     blc_dim dim;
     
     dim.length=length;
@@ -160,12 +152,12 @@ void blc_array::add_dim(int length, int step){
     total_length=size/get_type_size();
 }
 
-void blc_array::add_dim(int length){
+void blc_array::add_dim(size_t length){
     if (dims_nb==0) add_dim(length, get_type_size());
     else add_dim(length, dims[dims_nb-1].length*dims[dims_nb-1].step);
 }
 
-void blc_array::set_dims(int dims_nb, int length, ...){
+void blc_array::set_dims(int dims_nb, size_t length, ...){
     blc_dim *dim;
     va_list args;
     
@@ -181,7 +173,7 @@ void blc_array::set_dims(int dims_nb, int length, ...){
         size*=length;
         dim->step=1;
         dim->length=length;
-        length=va_arg(args, int);
+        length=va_arg(args, size_t);
     }
     va_end(args);
     total_length=size/get_type_size();
@@ -634,35 +626,62 @@ blc_array *blc_array_new_void(){
     return new blc_array();
 }
 
-blc_array *blc_array_new( uint32_t type, uint32_t format, int dims_nb, int length0, ...){
+blc_array *blc_array_new( uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
     va_list arguments;
+    vector<size_t> lengths(dims_nb, length0);
     va_start(arguments, length0);
-    return new blc_array(type, format, dims_nb, length0, arguments);
+    for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
     va_end(arguments);
+    
+    return new blc_array(type, format, lengths);
 }
 
 void blc_array_delete(blc_array *array){
     delete array;
 }
 
+uint32_t blc_array_get_type(blc_array *array){
+    return array->type;
+}
+
+uint32_t blc_array_get_format(blc_array *array){
+    return array->format;
+}
+
+int blc_array_get_dims_nb(blc_array *array){
+    return array->dims_nb;
+}
+
+blc_dim *blc_array_get_dims(blc_array *array){
+    return array->dims;
+}
+
+int blc_array_get_total_length(blc_array *array){
+    return array->total_length;
+}
+
 void *blc_array_get_data(blc_array *array){
     return array->data;
 }
 
-void blc_array_def(blc_array *array,  uint32_t type, uint32_t format, int dims_nb, int length0, ...){
+void blc_array_def(blc_array *array,  uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
     va_list arguments;
+    vector<size_t> lengths(dims_nb, length0);
     
     va_start(arguments, length0);
-    array->def_array(type, format, dims_nb, length0, arguments);
+    for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
     va_end(arguments);
+    array->def_array(type, format,lengths);
 }
 
-void blc_array_init(blc_array *array,  uint32_t type, uint32_t format, int dims_nb, int length0, ...){
+void blc_array_init(blc_array *array,  uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
     va_list arguments;
+    vector<size_t> lengths(dims_nb, length0);
     
     va_start(arguments, length0);
-    array->init(type, format, dims_nb, length0, arguments);
+    for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
     va_end(arguments);
+    new(array)blc_array(type, format, lengths);
 }
 
 // Envoie un message d'erreur avec name_of_file, name_of_function, number_of_line et affiche le message formate avec les parametres variables. Puis exit le programme avec le parametre EXIT_FAILURE. To be used with EXIT_ON_ERROR.
diff --git a/src/image/blc_image.cpp b/src/image/blc_image.cpp
index 279bca4..0a840a7 100644
--- a/src/image/blc_image.cpp
+++ b/src/image/blc_image.cpp
@@ -211,7 +211,7 @@ int blc_image_get_bytes_per_pixel(blc_array const *image)
             break;
         case 'MJPG':
         case 'JPEG':
-        case 'PNG':
+        case 'PNG ':
             return -1;
             break;
         default:
@@ -256,29 +256,30 @@ void blc_image_init(blc_array *array, uint32_t type, uint32_t format, size_t wid
  pixels_nb=width*height;
  }*/
 
-void blc_image_convert(blc_array *output, blc_array const *input)
-{
+void blc_image::convert(blc_array const &image){
+    blc_array *output=this;
+    blc_array const *input=&image; //This is waiting fully C++ methods
     int i;
     uint32_t output_format_str, input_format_str, input_type_str, output_type_str;
     
-    if (input->format == output->format)
+    if (input->format == format)
     {
-        if (input->type == output->type) memcpy(output->uchars, input->uchars, input->size);
-        else if (input->type == 'UIN8' && output->type == 'FL32') FOR_INV(i, output->size/sizeof(float))
-            output->floats[i] = (input->uchars[i] + 0.5f) / 256;
-        else if (input->type == 'FL32' && output->type == 'UIN8') FOR_INV(i, output->size)
-            output->uchars[i] = CLIP_UCHAR(input->floats[i]*256-0.5f);
-        else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format));
+        if (input->type == type) memcpy(uchars, input->uchars, input->size);
+        else if (input->type == 'UIN8' && type == 'FL32') FOR_INV(i, size/sizeof(float))
+            floats[i] = (input->uchars[i] + 0.5f) / 256;
+        else if (input->type == 'FL32' && type == 'UIN8') FOR_INV(i, size)
+            uchars[i] = CLIP_UCHAR(input->floats[i]*256-0.5f);
+        else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, this->format));
     }
     else
     {
         switch (input->format)
         {
             case 'BA81':
-                switch (output->format)
+                switch (this->format)
             {
                 case 'Y800':
-                    if (input->type == output->type) blc_Y800_from_BA81(output, input);
+                    if (input->type == type) blc_Y800_from_BA81(output, input);
                     else if (input->type == 'UIN8' && output->type == 'FL32') blc_Y800_float_from_BA81(output, input);
                     else EXIT_ON_ERROR("Conversion from type %.4s to type %.4s is not managed for conversion from format '%.4s' to format '%.4s'.", UINT32_TO_STRING(input_type_str, input->type), UINT32_TO_STRING(output_type_str, output->type), UINT32_TO_STRING(input_format_str, input->format), UINT32_TO_STRING(output_format_str, output->format));
                     break;
@@ -500,3 +501,11 @@ void blc_image_downscale(blc_array *output, blc_array const *input)
     }
 }
 
+
+START_EXTERN_C
+void blc_image_convert(blc_array *output, blc_array const *input){
+    
+    blc_image *image=(blc_image*)output;
+    image->convert(*input);
+}
+END_EXTERN_C
diff --git a/src/network/blc_array_tcp4_client.cpp b/src/network/blc_array_tcp4_client.cpp
index c38255e..d11a966 100644
--- a/src/network/blc_array_tcp4_client.cpp
+++ b/src/network/blc_array_tcp4_client.cpp
@@ -2,6 +2,10 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/errno.h>
+#include <sys/ioctl.h>
+
+
 #include <netdb.h>
 #include <unistd.h>
 #include <netinet/tcp.h>
@@ -9,7 +13,7 @@
 
 using namespace std;
 
-blc_array_tcp4_client::blc_array_tcp4_client(blc_array *array, string const &address, string const &port_name):array(array){
+blc_array_tcp4_client::blc_array_tcp4_client(string const &address, string const &port_name){
     int ret;
     struct addrinfo hints, *results;
 
@@ -27,8 +31,13 @@ blc_array_tcp4_client::blc_array_tcp4_client(blc_array *array, string const &add
     SYSTEM_ERROR_CHECK(setsockopt(socket_fd, IPPROTO_TCP, TCP_NODELAY, &flags, sizeof(flags)), -1, nullptr); //Disable Naggle algorithm. Packet are send even if they are small
     SYSTEM_ERROR_CHECK(connect(socket_fd, results->ai_addr, results->ai_addrlen), -1, nullptr);
     freeaddrinfo(results);
-    if (array->dims==nullptr) read_properties();
-    else EXIT_ON_ERROR("The local array is already defined.");
+    read_properties();
+    allocate();
+}
+
+blc_array_tcp4_client::blc_array_tcp4_client(string const &address, string const &port_name, uint32_t type, uint32_t format, vector<size_t> const &lengths):blc_array_tcp4_client(address, port_name){
+    def_array(type, format, lengths);
+    allocate();
 }
 
 void blc_array_tcp4_client::read_properties(){
@@ -38,19 +47,25 @@ void blc_array_tcp4_client::read_properties(){
     for (size_t read_nb=0; read_nb < properties.size(); read_nb+=static_cast<size_t>(ret)){
         SYSTEM_ERROR_CHECK(ret=read(socket_fd, properties.data()+read_nb, properties.size()-read_nb), -1, nullptr);
     }
-    array->sscan_properties(properties.data()); // The array will need allocation
+    sscan_properties(properties.data()); // The array will need allocation
 }
 
-void blc_array_tcp4_client::read_data(){
+int blc_array_tcp4_client::recv_data(){
     ssize_t ret;
+    ret=recv(socket_fd, chars, size, MSG_WAITALL);
+    if (ret==-1) return errno;
+    else return 0;
+}
 
-    for (size_t read_nb=0; read_nb<array->size; read_nb+=static_cast<size_t>(ret)){
-        SYSTEM_ERROR_CHECK(ret=read(socket_fd, array->chars+read_nb, array->size-read_nb), -1, nullptr);
-    }
+int blc_array_tcp4_client::bytes_to_read(){
+
+    int bytes_nb;
+    SYSTEM_ERROR_CHECK(ioctl(socket_fd, FIONREAD, &bytes_nb), -1, nullptr);
+    return bytes_nb;
 }
 
 void blc_array_tcp4_client::send_data(){
-    SYSTEM_ERROR_CHECK(write(socket_fd, array->data, array->size), -1, nullptr);
+    SYSTEM_ERROR_CHECK(write(socket_fd, data, size), -1, nullptr);
 }
 
 blc_array_tcp4_client::~blc_array_tcp4_client(){
@@ -59,8 +74,30 @@ blc_array_tcp4_client::~blc_array_tcp4_client(){
 
 
 START_EXTERN_C
-blc_array_tcp4_client *blc_array_tcp4_client_new(blc_array *array, const char *address, const char* port){
-    return new blc_array_tcp4_client(array, address, port);
+blc_array_tcp4_client *blc_array_tcp4_client_new_void( char const *address,  char const *port){
+    return new blc_array_tcp4_client(address, port);
+}
+
+blc_array_tcp4_client *blc_array_tcp4_client_new( char const *address, char const *port_name, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
+    va_list arguments;
+    vector<size_t> lengths(dims_nb, length0);
+    
+    va_start(arguments, length0);
+    for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
+    va_end(arguments);
+    return new blc_array_tcp4_client(address, port_name, type, format, lengths);
+}
+
+int blc_array_tcp4_client_recv_data(blc_array_tcp4_client *client){
+    return client->recv_data();
+}
+
+int blc_array_tcp4_client_bytes_to_read(blc_array_tcp4_client *client){
+    return client->bytes_to_read();
+}
+
+void blc_array_tcp4_client_send_data(blc_array_tcp4_client *client){
+    client->send_data();
 }
 
 void blc_array_tcp4_client_delete(blc_array_tcp4_client *client){
diff --git a/src/network/blc_array_tcp4_server.cpp b/src/network/blc_array_tcp4_server.cpp
index 23c2a3a..4d72794 100644
--- a/src/network/blc_array_tcp4_server.cpp
+++ b/src/network/blc_array_tcp4_server.cpp
@@ -2,6 +2,7 @@
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <sys/ioctl.h>
 #include <netdb.h>
 #include <unistd.h>
 #include <netinet/tcp.h>
@@ -9,7 +10,7 @@
 
 using namespace std;
 
-blc_array_tcp4_server::blc_array_tcp4_server(blc_array *array, string const &port_name):array(array){
+blc_array_tcp4_server::blc_array_tcp4_server(string const &port_name){
     int ret, error;
     struct addrinfo hints, *results;
 
@@ -31,6 +32,14 @@ blc_array_tcp4_server::blc_array_tcp4_server(blc_array *array, string const &por
     SYSTEM_ERROR_CHECK(listen(socket_fd, 1), -1, nullptr); /* Max one connection*/
 }
 
+/**
+ If you do not want allocate data, use 'blc_array_tcp4_server(string const &port_name)' then '''server->def_array( type,  format, lengths);'''
+ */
+blc_array_tcp4_server::blc_array_tcp4_server(string const &port_name, uint32_t type, uint32_t format, vector<size_t> const &lengths):blc_array_tcp4_server(port_name){
+    def_array(type, format, lengths);
+    allocate();
+}
+
 int blc_array_tcp4_server::wait_connection(){
     struct sockaddr_storage client_storage;
     socklen_t client_addr_len=sizeof(client_storage);
@@ -38,7 +47,7 @@ int blc_array_tcp4_server::wait_connection(){
     client_socket=accept(socket_fd, reinterpret_cast<struct sockaddr*>(&client_storage), &client_addr_len);
 
     if (client_socket==-1) return errno;
-    if (array->dims!=nullptr) send_properties();
+    if (dims!=nullptr) send_properties();
     return 0;
 }
 
@@ -46,16 +55,16 @@ void blc_array_tcp4_server::send_properties(){
     size_t length;
     vector<char> properties(1024);
 
-    length=static_cast<size_t>(array->sprint_properties(properties.data(), properties.size()-1));
+    length=static_cast<size_t>(sprint_properties(properties.data(), properties.size()-1));
     properties[length]=0;
     SYSTEM_ERROR_CHECK(write(client_socket, properties.data(), properties.size()), -1, nullptr);
 }
 
-int blc_array_tcp4_server::read_data(){
+int blc_array_tcp4_server::recv_data(){
     ssize_t ret;
 
-    for (size_t read_nb=0; read_nb<array->size; read_nb+=static_cast<size_t>(ret)){
-        ret=read(client_socket, array->chars+read_nb, array->size-read_nb);
+    for (size_t read_nb=0; read_nb<size; read_nb+=static_cast<size_t>(ret)){
+        ret=read(client_socket, chars+read_nb, size-read_nb);
         if (ret==-1) return errno;
     }
     return 0;
@@ -63,7 +72,7 @@ int blc_array_tcp4_server::read_data(){
 
 int blc_array_tcp4_server::send_data(){
     ssize_t ret;
-    ret=write(client_socket, array->data, array->size);
+    ret=write(client_socket, data, size);
     if (ret==-1) {
         if (errno==ECONNRESET) {
             SYSTEM_ERROR_CHECK(close(client_socket), -1, "client_socket %d", client_socket);
@@ -74,15 +83,37 @@ int blc_array_tcp4_server::send_data(){
     else return 0;
 }
 
+int blc_array_tcp4_server::bytes_to_send(){
+    int bytes_to_send;
+    SYSTEM_ERROR_CHECK(ioctl(client_socket, TIOCOUTQ, &bytes_to_send), -1, "client socket (%d)", client_socket);
+    return bytes_to_send;
+}
+
 blc_array_tcp4_server::~blc_array_tcp4_server(){
     SYSTEM_ERROR_CHECK(close(socket_fd), -1, nullptr);
 }
 
+START_EXTERN_C
+blc_array_tcp4_server *blc_array_tcp4_server_new_void(char const*port_name){
+    return new blc_array_tcp4_server(port_name);
+}
+
+blc_array_tcp4_server *blc_array_tcp4_server_new(char const*port_name, uint32_t type, uint32_t format, int dims_nb, size_t length0, ...){
+    va_list arguments;
+    vector<size_t> lengths(dims_nb, length0);
+    
+    va_start(arguments, length0);
+    for (int i=1; i<dims_nb; i++) lengths[i] = va_arg(arguments, size_t);
+    va_end(arguments);
+    return new blc_array_tcp4_server(port_name, type, format, lengths);
+}
 
+void blc_array_tcp4_server_recv_data(blc_array_tcp4_server *server){
+    server->recv_data();
+}
 
-START_EXTERN_C
-blc_array_tcp4_server *blc_array_tcp4_server_new(blc_array *array, char const*port_name){
-    return new blc_array_tcp4_server(array, port_name);
+void blc_array_tcp4_server_send_data(blc_array_tcp4_server *server){
+    server->send_data();
 }
 
 int blc_array_tcp4_server_wait_connection(blc_array_tcp4_server *server){
diff --git a/src/network/blc_network.cpp b/src/network/blc_network.cpp
index ea9b787..b6c779b 100644
--- a/src/network/blc_network.cpp
+++ b/src/network/blc_network.cpp
@@ -15,8 +15,7 @@
 #include <sys/types.h>
 #include <sys/errno.h>
 #include <sys/ioctl.h>
- #include <net/if.h>
-
+#include <net/if.h>
 #include <string>
 
 using namespace std;
diff --git a/test/network/CMakeLists.txt b/test/network/CMakeLists.txt
new file mode 100644
index 0000000..3778f4f
--- /dev/null
+++ b/test/network/CMakeLists.txt
@@ -0,0 +1,22 @@
+# Copyright  ETIS — ENSEA, Université de Cergy-Pontoise, CNRS (2011 - 2016)
+# Author: Arnaud Blanchard
+# This software is governed by the CeCILL v2.1 license under French law and abiding by the rules of distribution of free software.
+# You can use, modify and/ or redistribute the software under the terms of the CeCILL v2.1 license as circulated by CEA, CNRS and INRIA at the following URL "http://www.cecill.info".
+# As a counterpart to the access to the source code and  rights to copy, modify and redistribute granted by the license,
+# users are provided only with a limited warranty and the software's author, the holder of the economic rights,  and the successive licensors have only limited liability.
+# In this respect, the user's attention is drawn to the risks associated with loading, using, modifying and/or developing or reproducing the software by the user in light of its specific status of free software,
+# that may mean  that it is complicated to manipulate, and that also therefore means that it is reserved for developers and experienced professionals having in-depth computer knowledge.
+# Users are therefore encouraged to load and test the software's suitability as regards their requirements in conditions enabling the security of their systems and/or data to be ensured  and, more generally, to use and operate it in the same conditions as regards security.
+# The fact that you are presently reading this means that you have had knowledge of the CeCILL v2.1 license and that you accept its terms. 
+
+cmake_minimum_required(VERSION 2.6)
+project(t_net_writer)
+
+find_package(blc_network REQUIRED)
+
+add_definitions(${BL_DEFINITIONS})
+include_directories(${BL_INCLUDE_DIRS})
+add_executable(${PROJECT_NAME} main.cpp)
+target_link_libraries(${PROJECT_NAME} ${BL_LIBRARIES})
+
+
diff --git a/test/t_array_tcp4_client/CMakeLists.txt b/test/t_array_tcp4_client/CMakeLists.txt
new file mode 100644
index 0000000..60f0f87
--- /dev/null
+++ b/test/t_array_tcp4_client/CMakeLists.txt
@@ -0,0 +1,8 @@
+cmake_minimum_required(VERSION 3.13)
+
+project(t_array_tcp4_client)
+
+find_package(blc REQUIRED)
+
+add_executable(t_array_tcp4_client t_array_tcp4_client.cpp)
+target_link_libraries(t_array_tcp4_client PRIVATE blc)
diff --git a/test/t_array_tcp4_client/t_array_tcp4_client.cpp b/test/t_array_tcp4_client/t_array_tcp4_client.cpp
new file mode 100644
index 0000000..732813b
--- /dev/null
+++ b/test/t_array_tcp4_client/t_array_tcp4_client.cpp
@@ -0,0 +1,16 @@
+#include "blc.h"
+
+int main(int argc, char**argv){
+    
+    ///Start a new client with a connection to the server
+    blc_array_tcp4_client client("localhost", "31440");
+    fprintf(stderr, "Connected\nPress 'q' to quit\n");
+    
+    do{
+        fgets(client.chars, client.size, stdin);
+        client.send_data();
+    }while(strcmp(client.chars, "q\n")!=0);
+    
+    //We do not need to close the connection as it will be done by the destruction of server
+    return EXIT_SUCCESS;
+}
diff --git a/test/t_array_tcp4_server/CMakeLists.txt b/test/t_array_tcp4_server/CMakeLists.txt
new file mode 100644
index 0000000..a6f2e27
--- /dev/null
+++ b/test/t_array_tcp4_server/CMakeLists.txt
@@ -0,0 +1,9 @@
+cmake_minimum_required(VERSION 3.13)
+
+project(t_array_tcp4_server)
+
+find_package(blc REQUIRED)
+
+add_executable(t_array_tcp4_server t_array_tcp4_server.cpp)
+target_compile_features(t_array_tcp4_server PRIVATE cxx_std_14)
+target_link_libraries(t_array_tcp4_server PRIVATE blc)
diff --git a/test/t_array_tcp4_server/t_array_tcp4_server.cpp b/test/t_array_tcp4_server/t_array_tcp4_server.cpp
new file mode 100644
index 0000000..9cb561e
--- /dev/null
+++ b/test/t_array_tcp4_server/t_array_tcp4_server.cpp
@@ -0,0 +1,17 @@
+#include "blc.h"
+
+int main(int argc, char**argv){
+    
+    blc_array_tcp4_server server("31440", 'UIN8', 'TEXT', {1024});
+    fprintf(stderr, "waiting client\n");
+    server.wait_connection();
+    fprintf(stderr, "connected\n");
+    
+    do {
+        server.recv_data();
+        printf("text %s", server.chars);
+    }while(strcmp(server.chars, "q\n")!=0);
+
+    
+    return EXIT_SUCCESS;
+}
-- 
GitLab