Exemplo n.º 1
0
void ws_utf8_free(WsUtf8String *string)
{
    if (string == NULL)
        return;

    ws_free(string->data);
    ws_free(string);
}
Exemplo n.º 2
0
int ws__getLicenseRecordInfos(WS_ENV * soap, struct ws__LicenseRecordResponse *ret)
{
    s32 err_id = ERROR_SUCCESS;
    u8 	str_time[20];
    u32 i = 0;
    license_info_record_s* allLicense;
    struct LicenseRecord* allRecords;

    memset(str_time, '\0', sizeof(str_time));

    allLicense = (license_info_record_s*) ws_malloc(soap, sizeof(license_info_record_s));
    if(NULL == allLicense)
    {
        return ws_send_soap_error(soap, "ws_malloc fail!");
    }

    err_id = license_get_all_records(allLicense);

    if(ERROR_SUCCESS != err_id)
    {
        ws_free(soap, allLicense);
        return ws_send_soap_error(soap, "license_get_all_records errors");
    }

    allRecords = (struct LicenseRecord*)ws_malloc(soap, L_SIG_LIB_MAX_TYPE * sizeof(struct LicenseRecord));
    if(NULL == allRecords)
    {
        ws_free(soap, allLicense);
        return ws_send_soap_error(soap, "ws_malloc all records failed!");
    }


    ret->sum = ret->__size = ret->res_USCOREcount = L_SIG_LIB_MAX_TYPE;
    ret->__ptrres = allRecords;

    for(i = 0; i < L_SIG_LIB_MAX_TYPE ; i++)
    {
        allRecords[i].licenseType = allLicense->record[i].lib_type;
        allRecords[i].licenseName = ws_strdup(soap, (s8*)allLicense->record[i].lib_name);
        if(LICENSE_RECORD_VALID == allLicense->record[i].valid_flag)
        {
            strftime((s8*)str_time, 20, "%Y-%m-%d", localtime((time_t*)&(allLicense->record[i].expire_date)));
            allRecords[i].expireDate = ws_strdup(soap, (s8*)str_time);
            strftime((s8*)str_time, 20, "%Y-%m-%d", localtime((time_t*)&(allLicense->record[i].import_date)));
            allRecords[i].importDate = ws_strdup(soap, (s8*)str_time);
        }
        else
        {
            allRecords[i].expireDate = ws_strdup(soap, "");
            allRecords[i].importDate = ws_strdup(soap, "");
        }
    }

    return WS_OK;	
}
Exemplo n.º 3
0
/*****************************************************************************
 函 数 名  	: ws__getLicenseRecord
 功能描述  	: 获取指定类型的License记录
 输入参数  	: soap 		WS环境
 				  licenseType	license的类型
 				  ret			license记录结构	
 输出参数  	:  ret              license记录结构
 返 回 值  	: 
 调用函数  	: 
 被调函数  	: 
 
 修改历史  	:
 修改内容  	: 
*****************************************************************************/
int ws__getLicenseRecord(WS_ENV * soap, int licenseType, struct ws__LicenseRecordResponse *ret)
{
	s32 err_id = ERROR_SUCCESS;
	u8  str_time[20];
	license_single_record_s* single_record;
	struct LicenseRecord* record_info;

	memset(str_time, '\0', sizeof(str_time));
	single_record = (license_single_record_s*)ws_malloc(soap, sizeof(license_single_record_s));
	if(NULL == single_record)
	{
		return ws_send_soap_error(soap, "ws_malloc single_record fail!");
	}

	err_id = license_get_single_record(licenseType, single_record);
	if(ERROR_SUCCESS != err_id)
	{
		ws_free(soap, single_record);
		return ws_send_soap_error(soap, "license_get_single_record fail!");
	}
	
	if(NULL == single_record)
	{
		return WS_OK;
	}

	record_info = (struct LicenseRecord*)ws_malloc(soap,sizeof(struct LicenseRecord));
	if(NULL == record_info)
	{
		ws_free(soap, single_record);
		return ws_send_soap_error(soap, "ws_malloc record_info fail!");
	}

	ret->sum = ret->__size = ret->res_USCOREcount = 1;
	ret->__ptrres = record_info;

	record_info->licenseType = single_record->lib_type;
	record_info->licenseName = ws_strdup(soap, (s8*)single_record->lib_name);
	if(LICENSE_RECORD_VALID == single_record->valid_flag)
	{
		strftime((s8*)str_time, 20, "%Y-%m-%d", localtime((time_t*)&(single_record->expire_date)));
		record_info->expireDate = ws_strdup(soap, (s8*)str_time);
		strftime((s8*)str_time, 20, "%Y-%m-%d", localtime((time_t*)&(single_record->import_date)));
		record_info->importDate = ws_strdup(soap, (s8*)str_time);
	}
	else
	{
		record_info->expireDate = ws_strdup(soap, "");
		record_info->importDate = ws_strdup(soap, "");
	}

	return WS_OK;	
}
Exemplo n.º 4
0
void ws_f_destroy(WsFastMalloc *pool)
{
    WsFastMallocBlock *b, *bnext;

    if (pool == NULL)
        return;

    for (b = pool->blocks; b; b = bnext) {
        bnext = b->next;
        ws_free(b);
    }
    ws_free(pool);
}
Exemplo n.º 5
0
void ws_bc_free(WsBc *bc)
{
    WsUInt16 i;
    WsUInt8 j;

    if (bc == NULL)
        return;

    /* Free constants. */
    for (i = 0; i < bc->num_constants; i++) {
        WsBcConstant *c = &bc->constants[i];

        if (c->type == WS_BC_CONST_TYPE_UTF8_STRING)
            ws_free(c->u.v_string.data);
    }
    ws_free(bc->constants);

    /* Free pragmas. */
    ws_free(bc->pragmas);

    /* Free function names. */
    for (j = 0; j < bc->num_function_names; j++)
        ws_free(bc->function_names[j].name);
    ws_free(bc->function_names);

    /* Free functions. */
    for (j = 0; j < bc->num_functions; j++)
        ws_free(bc->functions[j].code);
    ws_free(bc->functions);

    /* Free the byte-code structure. */
    ws_free(bc);
}
Exemplo n.º 6
0
int ws_utf8_set_data(WsUtf8String *string, const unsigned char *data,
                     size_t len)
{
    size_t num_chars;

    if (!ws_utf8_verify(data, len, &num_chars))
        /* Malformed data. */
        return 0;

    /* Init `string' to empty. */
    ws_free(string->data);
    string->data = NULL;
    string->len = 0;
    string->num_chars = 0;

    /* Set the new data. */
    string->data = ws_memdup(data, len);
    if (string->data == NULL)
        return 0;

    string->len = len;
    string->num_chars = num_chars;

    return 1;
}
void my_free(my_t my) {
  if (my) {
    ws_free(my->ws);
    memset(my, 0, sizeof(struct my_struct));
    free(my);
  }
}
Exemplo n.º 8
0
void ws_stream_close(WsStream *stream)
{
    if (stream->close)
        (*stream->close)(stream->context);

    ws_free(stream);
}
Exemplo n.º 9
0
s32 ws__getSslPolicyInfo(WS_ENV* soap, struct ws__getSslPolicyInfoList *ret)
{
	sqlite3 *db=NULL;
	u32 count;
	u32 i;
	s8* str;
	sqlite3_res res=NULL;
	struct SslPolicyInfo *sslinfo;
	/* 打开数据库  */
	if(NULL ==(db = sqlite3_open_ex(1,SESSION_TREE_DB)))
	{
	   return WS_OK;
	}
	snprintf(g_sqlite_sql_buf,sizeof(g_sqlite_sql_buf),
			"SELECT COUNT(*) as count FROM tb_ssl_session;");
	sqlite3_exec_query_ex(db,g_sqlite_sql_buf,&res);
	sqlite3_get_u32_ex(res,0,"count",&count);
	if(count == 0)
	{
		goto label;
	}

	ret->ret.sum = (s32)count;
	ret->ret.__size = (s32)count;
	ret->ret.res_USCOREcount =(s32)count;
	sqlite3_res_free_ex(res);
	res = NULL;
	snprintf(g_sqlite_sql_buf,sizeof(g_sqlite_sql_buf),
			"SELECT * FROM tb_ssl_session;");
	sqlite3_exec_query_ex(db,g_sqlite_sql_buf,&res);

	sslinfo = (struct SslPolicyInfo *)ws_malloc(soap, count * sizeof(struct SslPolicyInfo));
	if(sslinfo == NULL)
	{
		ws_free(soap, sslinfo);
		goto label;
	}
	ret->ret.__ptrres = sslinfo;
	for(i=0;i<count;i++)
	{
		sqlite3_get_s32_ex(res, i, "id", &sslinfo[i].id);
		sqlite3_get_str_ex(res, i, "name", &str);
		sslinfo[i].name= ws_strdup(soap,str);		
		sqlite3_get_s32_ex(res, i, "agingtime", &sslinfo[i].agingtime);

	}
label:
	if (NULL != res)
	{
	  sqlite3_res_free_ex(res);
	  res = NULL;
	}
	if (NULL != db)
	{
	  sqlite3_close_ex(db);
	  db = NULL;
	}
	return WS_OK;
}
Exemplo n.º 10
0
void ws_hash_clear(WsHashPtr hash)
{
    WsHashItem *i, *n;
    size_t j;

    for (j = 0; j < WS_HASH_TABLE_SIZE; j++) {
        for (i = hash->items[j]; i; i = n) {
            n = i->next;
            if (hash->destructor)
                (*hash->destructor)(i->data, hash->destructor_context);

            ws_free(i->name);
            ws_free(i);
        }
        hash->items[j] = NULL;
    }
}
Exemplo n.º 11
0
void ws_hash_destroy(WsHashPtr hash)
{
    if (hash == NULL)
        return;

    ws_hash_clear(hash);
    ws_free(hash);
}
Exemplo n.º 12
0
static void file_close(void *context)
{
    WsStreamFileCtx *ctx = (WsStreamFileCtx *) context;

    if (ctx->close_fp)
        fclose(ctx->fp);

    ws_free(ctx);
}
Exemplo n.º 13
0
void ws_pragma_meta_body_free(WsCompilerPtr compiler, WsPragmaMetaBody *mb)
{
    if (mb == NULL)
        return;

    ws_lexer_free_utf8(compiler, mb->property_name);
    ws_lexer_free_utf8(compiler, mb->content);
    ws_lexer_free_utf8(compiler, mb->scheme);

    ws_free(mb);
}
Exemplo n.º 14
0
Arquivo: ws.c Projeto: markjeee/kannel
void ws_destroy(WsCompilerPtr compiler)
{
    if (compiler == NULL)
        return;

    ws_free(compiler);

#if WS_MEM_DEBUG
    if (ws_has_leaks())
        ws_dump_blocks();
#endif /* WS_MEM_DEBUG */
}
Exemplo n.º 15
0
void ws_bc_data_free(unsigned char *data)
{
    size_t len = WS_MB_UINT32_MAX_ENCODED_LEN;

    if (data == NULL)
        return;

    /* Decode the mb-encoded length so we know how much space it uses. */
    (void) ws_decode_mb_uint32(data + 1, &len);

    /* Now we can compute the beginning of the array `data'. */
    ws_free(data - (WS_MB_UINT32_MAX_ENCODED_LEN - len));
}
Exemplo n.º 16
0
s32 ws__getBgpAggInfo(WS_ENV * ws_env,s32 afi, s32 safi, s32 nstart, s32 nsize, struct BgpAggInfoRespone * ret )
{
    struct BgpAggInfo * out = NULL;
    web_bgp_aggregate_info_t * info = (void*)buff;
    s32 count ,i ;
    s32 sum = 0 , max = 0;
    u8  iptrans[INET6_ADDRSTRLEN];
    u8 *ipret=NULL;
    
    if( socket_api_write(WEB_BGP_APICMD_GET_AGG,NULL,0) < 0 )
        return ws_send_soap_error(ws_env,"send command error!");

    do{
        count = socket_api_read(WEB_BGP_APICMD_GET_AGG,info,SOCKET_API_BUFFER_SIZE);
        if( count <= 0 )
        {
            break;
        }
        if( max < sum + count )
        {
            void * tmp = ws_malloc(ws_env,(sum + count)*sizeof(struct BgpAggInfo));
            if( out != NULL )
            {
                memcpy(tmp,out,sum * sizeof(struct BgpAggInfo));
                ws_free(ws_env,out);
            }
            out = tmp ;
            max = sum + count ;
        }

        for(i=0;i<count;i++)
        {
            ipret = (u8*)inet_ntop((s32)info[i].p.family,(void*)&info[i].p.u,(s8*)iptrans,INET6_ADDRSTRLEN);
            if( ipret == NULL ) 
                continue;
            out[sum].addr = ws_strdup(ws_env,(s8*)ipret);
            out[sum].mask = info[i].p.prefixlen;
            out[sum].sonly= info[i].summary_only;
            out[sum].asset=info[i].as_set;
            sum++;
        }
    }while( ! socket_api_check_flag(SOCKET_API_FLAG_LASTONE) );

    ret->ret.sum = sum ;
    ret->ret.__ptrres = out ;
    ret->ret.__size = sum ;
    ret->ret.res_USCOREcount = sum ;

    return WS_OK;
}
Exemplo n.º 17
0
void ws_function(WsCompiler *compiler, WsBool externp, char *name,
                 WsUInt32 line, WsList *params, WsList *block)
{
    WsFunctionHash *hash;
    WsFunction *f = ws_realloc(compiler->functions,
                               ((compiler->num_functions + 1)
                                * sizeof(WsFunction)));

    if (f == NULL) {
        ws_free(name);
        ws_error_memory(compiler);
        return;
    }

    if (externp)
        compiler->num_extern_functions++;
    else
        compiler->num_local_functions++;

    compiler->functions = f;
    f = &compiler->functions[compiler->num_functions];

    f->findex = compiler->num_functions++;

    f->externp = externp;
    f->name = name;
    f->line = line;
    f->params = params;
    f->block = block;

    /* Update the function name hash. */

    hash = ws_function_hash(compiler, name);
    if (hash == NULL) {
        ws_error_memory(compiler);
        return;
    }

    if (hash->defined) {
        ws_src_error(compiler, line, "redefinition of `%s'", name);
        ws_src_error(compiler,
                     compiler->functions[hash->findex].line,
                     "`%s' previously defined here", name);
        return;
    }

    hash->defined = WS_TRUE;
    hash->findex = f->findex;
}
Exemplo n.º 18
0
s32 ws__showBgpNeighbor(WS_ENV * ws_env,s32 afi, s32 safi,s32 nstart, s32 nsize,struct BgpShowNeighborResponse * ret)
{
    s8 temp[SU_ADDRSTRLEN];
    s32 count = 0 , i = 0;
    s32 sum = 0 ;
    s32 max = 0;
    struct BgpShowNeighbor * out = NULL;
    web_bgp_neighbor_show_info_t * info = (void*)buff;

    if( socket_api_write(WEB_BGP_APICMD_SHOW_NBR,NULL,0) < 0 )
        return ws_send_soap_error(ws_env,"send command error!");

    do{
        count = socket_api_read(WEB_BGP_APICMD_SHOW_NBR,info,SOCKET_API_BUFFER_SIZE);
        if( count <= 0 )
        {
            break;
        }
        if( max < sum + count )
        {
            void * tmp = ws_malloc(ws_env,(sum + count)*sizeof(struct BgpShowNeighbor));
            if( out != NULL )
            {
                memcpy(tmp,out,sum * sizeof(struct BgpShowNeighbor));
                ws_free(ws_env,out);
            }
            out = tmp ;
            max = sum + count ;
        }
        for(i=0;i<count;i++)
        {
            out[sum].hostip = ws_strdup(ws_env, sockunion2str(&(info[i].su), temp, SU_ADDRSTRLEN) ) ;
            out[sum].asid   = info[i].asid ;
            out[sum].hostid = ws_strdup(ws_env,inet_ntoa(info[i].id));
            out[sum].state  = ws_strdup(ws_env,bgp_status_msg[(s32)info[i].state]);
            out[sum].localinterface = ws_strdup(ws_env,inet_ntoa(info[i].nexthop));
            out[sum].uptime = ws_strdup(ws_env,web_time_dump(info[i].t_uptime));
            out[sum].overtime = ws_strdup(ws_env,web_time_dump(info[i].t_dead));
            sum++;
        }
    }while( ! socket_api_check_flag(SOCKET_API_FLAG_LASTONE) );

    ret->ret.sum = sum ;
    ret->ret.__ptrres = out ;
    ret->ret.__size = sum ;
    ret->ret.res_USCOREcount = sum ;

    return WS_OK;
}
Exemplo n.º 19
0
void 
serial_tm_send_debug( IPMI_WS *ws )
/*----------------------------------------------------------------------------*/
{
	int i;
	
	printf( "[" );
	for( i = 0; i < ws->len_out; i++ ) { 
		printf( "%2.2x", ws->pkt_out[i] );
		if( i < ( ws->len_out - 1 ) )
			printf( " " );
	}
	printf( "]\n" );
	ws_free( ws );
}
Exemplo n.º 20
0
void ws_pragma_use(WsCompilerPtr compiler, WsUInt32 line, char *identifier,
                   WsUtf8String *url)
{
    WsPragmaUse *u = ws_calloc(1, sizeof(*u));
    WsPragmaUse *uold;

    /* Do we already know this pragma? */
    uold = ws_hash_get(compiler->pragma_use_hash, identifier);
    if (uold) {
        ws_src_error(compiler, line, "redefinition of pragma `%s'", identifier);
        ws_src_error(compiler, uold->line, "`%s' previously defined here",
                     identifier);
        goto error_cleanup;
    }

    if (u == NULL)
        goto error;

    u->line = line;

    /* Insert the URL to the byte-code module. */
    if (!ws_bc_add_const_utf8_string(compiler->bc, &u->urlindex, url->data,
                                     url->len))
        goto error;

    /* Add it to the use pragma hash. */
    if (!ws_hash_put(compiler->pragma_use_hash, identifier, u))
        goto error;

    /* Cleanup. */

    ws_lexer_free_block(compiler, identifier);
    ws_lexer_free_utf8(compiler, url);

    return;

    /* Error handling. */

error:

    ws_error_memory(compiler);

error_cleanup:

    ws_free(u);
    ws_lexer_free_block(compiler, identifier);
    ws_lexer_free_utf8(compiler, url);
}
Exemplo n.º 21
0
int main(int argc, char ** argv)
{
   char buf[8000];
   websocket_t ws;
   int fd, plen, len;

   fd = ws_connect();

   ws_init(&ws, fd, 1000, 1);

   for (int eof = 0; !eof;)
   {
      for (len = 0; !eof;)
      {
         if ((plen = read(0, buf + len, sizeof(buf) - len)) == -1)
            exit(1);

         // check for eof
         eof = plen == 0;

         len += plen;
         // check for "\n.\n" (single period on line)
         if (len > 2 && buf[len - 1] == '\n' &&
               buf[len - 3] == '\n' && buf[len - 2] == '.')
         {
            // remove it
            len -= 2;
            break;
         }
      }

      if ((ws_write(&ws, buf, len)) == -1)
         exit(1);

      if ((plen = ws_read(&ws, buf, sizeof(buf))) == -1)
         exit(1);

      if (!plen)
         break;

      write(1, buf, plen);
   }

   ws_free(&ws);

   close(fd);
   return 0;
}
Exemplo n.º 22
0
WsBool ws_hash_put(WsHashPtr hash, const char *name, void *data)
{
    WsHashItem *i;
    size_t h = count_hash(name);

    for (i = hash->items[h]; i; i = i->next) {
        if (strcmp(i->name, name) == 0) {
            /* Found it. */

            /* Destroy the old item */
            if (hash->destructor)
                (*hash->destructor)(i->data, hash->destructor_context);

            i->data = data;

            return WS_FALSE;
        }
    }

    /* Must create a new mapping. */
    i = ws_calloc(1, sizeof(*i));

    if (i == NULL)
        return WS_FALSE;

    i->name = ws_strdup(name);
    if (i->name == NULL) {
        ws_free(i);
        return WS_FALSE;
    }

    i->data = data;

    /* Link it to our hash. */
    i->next = hash->items[h];
    hash->items[h] = i;

    return WS_TRUE;
}
Exemplo n.º 23
0
Arquivo: ws.c Projeto: markjeee/kannel
void ws_lexer_free_block(WsCompiler *compiler, void *ptr)
{
    int i;

    if (ptr == NULL)
        return;

    for (i = compiler->lexer_active_list_size - 1; i >= 0; i--) {
        if (compiler->lexer_active_list[i] == ptr) {
            memmove(&compiler->lexer_active_list[i],
                    &compiler->lexer_active_list[i + 1],
                    (compiler->lexer_active_list_size - i - 1) * sizeof(void *));
            compiler->lexer_active_list_size--;

            ws_free(ptr);
            return;
        }
    }

    ws_fatal("ws_lexer_free_block(): unknown block 0x%lx",
             (unsigned long) ptr);
}
Exemplo n.º 24
0
WsFunctionHash *ws_function_hash(WsCompilerPtr compiler, char *name)
{
    WsFunctionHash *i = ws_hash_get(compiler->functions_hash, name);

    if (i)
        return i;

    /* Must create a new mapping. */

    i = ws_calloc(1, sizeof(*i));
    if (i == NULL) {
        ws_error_memory(compiler);
        return NULL;
    }

    if (!ws_hash_put(compiler->functions_hash, name, i)) {
        ws_free(i);
        ws_error_memory(compiler);
        return NULL;
    }

    return i;
}
Exemplo n.º 25
0
WsNamespace *ws_variable_define(WsCompilerPtr compiler, WsUInt32 line,
                                WsBool variablep, char *name)
{
    WsNamespace *ns;

    /* Is the symbol already defined? */
    ns = ws_hash_get(compiler->variables_hash, name);
    if (ns) {
        ws_src_error(compiler, line, "redeclaration of `%s'", name);
        ws_src_error(compiler, ns->line, "`%s' previously declared here", name);
        return NULL;
    }

    /* Can we still define more variables? */
    if (compiler->next_vindex > 255) {
        /* No we can't. */
        ws_src_error(compiler, line, "too many local variables");
        return NULL;
    }

    ns = ws_calloc(1, sizeof(*ns));
    if (ns == NULL) {
        ws_error_memory(compiler);
        return NULL;
    }

    ns->line = line;
    ns->vindex = compiler->next_vindex++;

    if (!ws_hash_put(compiler->variables_hash, name, ns)) {
        ws_free(ns);
        ws_error_memory(compiler);
        return NULL;
    }

    return ns;
}
Exemplo n.º 26
0
void 
serial_tm_send( IPMI_WS *ws )
/*----------------------------------------------------------------------------*/
{
	int i;
	char buf[128];
	char *ptr = buf;
	int pos = 0;
	
	pos = sprintf( ptr, "[" );
	ptr += pos;	
	for( i = 0; i < ws->len_out; i++ ) {
		pos = sprintf( ptr, "%2.2x", ws->pkt_out[i] );
		ptr += pos;	
		if( i < ( ws->len_out - 1 ) ) {
			pos = sprintf( ptr, " " );
			ptr += pos;
		}
	}
	sprintf( ptr, "]\n" );
	//printf( "%s", buf );
	write( fd, buf, strlen( buf ) );
	ws_free( ws );
}
Exemplo n.º 27
0
static void function_hash_destructor(void *item, void *context)
{
    ws_free(item);
}
Exemplo n.º 28
0
static void pragma_use_hash_destructor(void *item, void *context)
{
    ws_free(item);
}
Exemplo n.º 29
0
static void variable_hash_destructor(void *item, void *context)
{
    ws_free(item);
}
Exemplo n.º 30
0
Arquivo: url.c Projeto: AndreRH/wine
/**************************************************************************
 *          WsEncodeUrl		[webservices.@]
 */
HRESULT WINAPI WsEncodeUrl( const WS_URL *base, ULONG flags, WS_HEAP *heap, WS_STRING *ret,
                            WS_ERROR *error )
{
    static const WCHAR fmtW[] = {':','%','u',0};
    ULONG len = 0, len_scheme, len_enc, ret_size;
    const WS_HTTP_URL *url = (const WS_HTTP_URL *)base;
    const WCHAR *scheme;
    WCHAR *str, *p, *q;
    ULONG port = 0;
    HRESULT hr;

    TRACE( "%p %08x %p %p %p\n", base, flags, heap, ret, error );
    if (error) FIXME( "ignoring error parameter\n" );

    if (!url || !heap || !ret) return E_INVALIDARG;
    if (flags)
    {
        FIXME( "unimplemented flags %08x\n", flags );
        return E_NOTIMPL;
    }
    if (!(scheme = scheme_str( url->url.scheme, &len_scheme ))) return WS_E_INVALID_FORMAT;
    len = len_scheme + 3; /* '://' */
    len += 6; /* ':65535' */

    if ((hr = url_encode_size( url->host.chars, url->host.length, "", &len_enc )) != S_OK)
        return hr;
    len += len_enc;

    if ((hr = url_encode_size( url->path.chars, url->path.length, "/", &len_enc )) != S_OK)
        return hr;
    len += len_enc;

    if ((hr = url_encode_size( url->query.chars, url->query.length, "/?", &len_enc )) != S_OK)
        return hr;
    len += len_enc + 1; /* '?' */

    if ((hr = url_encode_size( url->fragment.chars, url->fragment.length, "/?", &len_enc )) != S_OK)
        return hr;
    len += len_enc + 1; /* '#' */

    ret_size = len * sizeof(WCHAR);
    if (!(str = ws_alloc( heap, ret_size ))) return WS_E_QUOTA_EXCEEDED;

    memcpy( str, scheme, len_scheme * sizeof(WCHAR) );
    p = str + len_scheme;
    p[0] = ':';
    p[1] = p[2] = '/';
    p += 3;

    if ((hr = url_encode( url->host.chars, url->host.length, p, "", &len_enc )) != S_OK)
        goto error;
    p += len_enc;

    if (url->portAsString.length)
    {
        q = url->portAsString.chars;
        len = url->portAsString.length;
        while (len && isdigitW( *q ))
        {
            if ((port = port * 10 + *q - '0') > 65535)
            {
                hr = WS_E_INVALID_FORMAT;
                goto error;
            }
            q++; len--;
        }
        if (url->port && port != url->port)
        {
            hr = E_INVALIDARG;
            goto error;
        }
    } else port = url->port;

    if (port == default_port( url->url.scheme )) port = 0;
    if (port)
    {
        WCHAR buf[7];
        len = sprintfW( buf, fmtW, port );
        memcpy( p, buf, len * sizeof(WCHAR) );
        p += len;
    }

    if ((hr = url_encode( url->path.chars, url->path.length, p, "/", &len_enc )) != S_OK)
        goto error;
    p += len_enc;

    if (url->query.length)
    {
        *p++ = '?';
        if ((hr = url_encode( url->query.chars, url->query.length, p, "/?", &len_enc )) != S_OK)
            goto error;
        p += len_enc;
    }

    if (url->fragment.length)
    {
        *p++ = '#';
        if ((hr = url_encode( url->fragment.chars, url->fragment.length, p, "/?", &len_enc )) != S_OK)
            goto error;
        p += len_enc;
    }

    ret->length = p - str;
    ret->chars  = str;
    return S_OK;

error:
    ws_free( heap, str, ret_size );
    return hr;
}