diff --git a/CMakeLists.txt b/CMakeLists.txt index 1744f786b8b22ed6a2e93a672c794eeb1d6700bf..ab60ff33a7afdda23a0bcff925a0c231ce1714d8 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 bb1802c12b56c3c85aaa5e4d050f9fb6f38470dd..0000000000000000000000000000000000000000 --- 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 0000000000000000000000000000000000000000..61079b7bb03e2e294286078275fc401f6f802859 --- /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 cd97fd40a43dc6680b4eaa10a1288c1d99ee12b7..55b2a44f3f790c4c44235676ddfa2533c21b1092 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 3b7cfa2cd527d3ae8f7512ffdfb97b4c8aa3d2ca..f658a24753d481502928dc37ace068aacd5804dc 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 c915f69ea90d3058361c13be91c07f2fb3b3012a..5a444ff0d761447f84a6a01097018bfebc43ca06 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 f4f33bf69a4660fff6a6fe1cddafd06c07f6b6e6..7307a9851605c828d3d1c227acce7a22fc25c5f4 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 6bed35c1bff263e04d0dd22e401af490ae257f32..5a690534e5738b6583ae4203579c501d80ff7595 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 3881fddfbef304c8cf009801db631775ca4dafe5..20ba3b2e7ebbf85166464bb137362766c64ce532 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 9d3ebb5356e19dbe4839e1c0491858221c37d80f..c58ba1b7b41827cdef1dbcf405e690cedf4ff700 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 d6f9ec4b02a25cb83dd44f538304a80ac5805817..033524b8268e50ddeb28ae2c9bf3877572072444 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 7d99cee224a7dacb8a02228fbf2e7cb404bdf003..e3ea91e4169408fcb1d4c82272fd32ac89203c16 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 6659152a31f57624418deeb1a518856b440c0b8c..f88d5ec62ca5b1b29755d39e20acc22277855fc3 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 279bca4b69a6b0acbcc4c41ea7a35f55690d1730..0a840a7b87dd15cac98480d39f9b79947ca0b040 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=ℑ //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 c38255e1c31c0d70d4c3e9377e4a12f40c48ce14..d11a9665153b1ae58c8c66a57f5deed235ef2c00 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 23c2a3abfeefb502a0d285d2afd41ae0aeaed4da..4d727947cf1f9bb700aea71ec4a7959f00fdc95b 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 ea9b7872704e8f542ac1a898ed9173cc81d878b5..b6c779b1adc33cea8c8197303dbd01ad8ca25a8d 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 0000000000000000000000000000000000000000..3778f4f043da1feaa0eebb6d7d07476e4c0a9ab1 --- /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 0000000000000000000000000000000000000000..60f0f879ed7a345d9d8bf27bd249f6f9012c345a --- /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 0000000000000000000000000000000000000000..732813b1d20320b8324c36fc199ff2cee82e7368 --- /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 0000000000000000000000000000000000000000..a6f2e27d650fdfe08a337a5eb5fe3daeecd1e46e --- /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 0000000000000000000000000000000000000000..9cb561e908f0569b9934332a62bd38b86ba2c64f --- /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; +}