/* This file is part of Lcrzo.
*/

/*-------------------------------------------------------------*/
#if defined LCRZODEF_SYSTEM_Unix
#elif defined LCRZODEF_SYSTEM_Windows
int lcrzo_priv_ipc_handle_write(lcrzo_ipc *pipc, 
			    lcrzo_constdata data,
			    lcrzo_int32 datasize);
int lcrzo_priv_ipc_handle_write(lcrzo_ipc *pipc, 
			    lcrzo_constdata data,
			    lcrzo_int32 datasize)
{ lcrzo_int32 blocksize, i;
  lcrzo_uint32 writtensize;
  BOOL err;
  
  /*nothing to write*/
  if (data==NULL || datasize==0) return(LCRZO_ERR_OK);

  for ( i=0 ; i<datasize ; )
  { /*determine block size*/
    blocksize=datasize-i;
    if (blocksize>LCRZO_PRIV_WRITEMAXMSGSIZE)
      blocksize=LCRZO_PRIV_WRITEMAXMSGSIZE;
    /*write a block*/
    err=WriteFile(pipc->writehandle[pipc->side], 
		  data+i, blocksize, &writtensize, NULL);
    if (!err) return(LCRZO_ERR_FUWRITEFILE);
    /*update the current position*/
    i+=writtensize;
  }

  return(LCRZO_ERR_OK);
}
#else
 #error "Unknown value for LCRZODEF_SYSTEM"
#endif

/*-------------------------------------------------------------*/
int lcrzo_priv_ipc_writetlv(lcrzo_ipc *pipc, lcrzo_uint16 type,
			    lcrzo_constdata donnees,
			    lcrzo_int32 nboctdonnees)
{ lcrzo_uint8 typelongueur[6];

  /*parameters verification*/
  if (pipc==NULL) return(LCRZO_ERR_PANULLPTR);
  if (donnees==NULL && nboctdonnees) return(LCRZO_ERR_PANULLPTRSIZE);
  if (nboctdonnees<0) return(LCRZO_ERR_PATOOLOW);
  if (pipc->side!=0&&pipc->side!=1) return(LCRZO_ERR_LOIPCSIDENOTSET);
  if (!pipc->openforwriting) return(LCRZO_ERR_LONOTOPENFORWRITING);

  /*preparation du type-longueur*/
  typelongueur[0]=(lcrzo_uint8)(type>>8);
  typelongueur[1]=(lcrzo_uint8)(type&0xFF);
  typelongueur[2]=(lcrzo_uint8)(nboctdonnees>>24);
  typelongueur[3]=(lcrzo_uint8)((nboctdonnees>>16)&0xFF);
  typelongueur[4]=(lcrzo_uint8)((nboctdonnees>>8)&0xFF);
  typelongueur[5]=(lcrzo_uint8)(nboctdonnees&0xFF);

#if defined LCRZODEF_SYSTEM_Unix
  { int ret;
    /*ignore SIGPIPE to have errno==EPIPE (man 2 write)*/
    signal(SIGPIPE, SIG_IGN);

    /*ecriture du type-longueur*/
    ret=lcrzo_priv_fd_write(pipc->writepipe[pipc->side], typelongueur, 6);
    if ( ret!=LCRZO_ERR_OK )
    { if ( ret==LCRZO_ERR_FUWRITE && errno==EPIPE )
      { errno=0;
        return(LCRZO_ERR_LONOTOPENFORWRITING);
      }
      else
        return(ret);
    }

    /*ecriture des donnees*/
    ret=lcrzo_priv_fd_write(pipc->writepipe[pipc->side], donnees,nboctdonnees);
    if ( ret!=LCRZO_ERR_OK )
    { if ( ret==LCRZO_ERR_FUWRITE && errno==EPIPE )
      { errno=0;
        return(LCRZO_ERR_LONOTOPENFORWRITING);
      }
      else
        return(ret);
    }

    /*restore signal*/
    signal(SIGPIPE, SIG_DFL);
  }
#elif defined LCRZODEF_SYSTEM_Windows
  lcrzo_er(lcrzo_priv_ipc_handle_write(pipc, typelongueur, 6));
  lcrzo_er(lcrzo_priv_ipc_handle_write(pipc, donnees, nboctdonnees));
#else
 #error "Unknown value for LCRZODEF_SYSTEM"
#endif

  return(LCRZO_ERR_OK);
}

