216 lines
6.4 KiB
C
216 lines
6.4 KiB
C
/*
|
|
* Copyright 2008 Arsen Chaloyan
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef __APT_TEXT_STREAM_H__
|
|
#define __APT_TEXT_STREAM_H__
|
|
|
|
/**
|
|
* @file apt_text_stream.h
|
|
* @brief Text Stream Parse/Generate Routine
|
|
*/
|
|
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include "apt_string.h"
|
|
#include "apt_pair.h"
|
|
|
|
APT_BEGIN_EXTERN_C
|
|
|
|
/** Named tokens */
|
|
|
|
/** Space */
|
|
#define APT_TOKEN_SP ' '
|
|
/** Carrige return */
|
|
#define APT_TOKEN_CR 0x0D
|
|
/** Line feed */
|
|
#define APT_TOKEN_LF 0x0A
|
|
|
|
/** Text stream declaration */
|
|
typedef struct apt_text_stream_t apt_text_stream_t;
|
|
|
|
/** Text stream is used for message parsing and generation */
|
|
struct apt_text_stream_t {
|
|
/** Text stream */
|
|
apt_str_t text;
|
|
/** Current position in the buffer */
|
|
char *pos;
|
|
};
|
|
|
|
/**
|
|
* Navigate through the lines of the text stream (message).
|
|
* @param stream the text stream to navigate
|
|
* @param line the read line to return
|
|
* @return TRUE if the length of the line > 0, otherwise FALSE
|
|
*/
|
|
APT_DECLARE(apt_bool_t) apt_text_line_read(apt_text_stream_t *stream, apt_str_t *line);
|
|
|
|
/**
|
|
* Navigate through the headers (name:value pairs) of the text stream (message).
|
|
* @param stream the text stream to navigate
|
|
* @param pair the read pair to return
|
|
* @return TRUE if the length of the read name > 0, otherwise FALSE
|
|
*/
|
|
APT_DECLARE(apt_bool_t) apt_text_header_read(apt_text_stream_t *stream, apt_pair_t *pair);
|
|
|
|
/**
|
|
* Navigate through the fields of the line.
|
|
* @param stream the text stream to navigate
|
|
* @param separator the field separator
|
|
* @param skip_spaces whether to skip spaces or not
|
|
* @param field the read field to return
|
|
* @return TRUE if the length of the field > 0, otherwise FALSE
|
|
*/
|
|
APT_DECLARE(apt_bool_t) apt_text_field_read(apt_text_stream_t *stream, char separator, apt_bool_t skip_spaces, apt_str_t *field);
|
|
|
|
|
|
|
|
/** Generate header */
|
|
APT_DECLARE(apt_bool_t) apt_text_header_generate(const apt_pair_t *pair, apt_text_stream_t *text_stream);
|
|
|
|
/** Generate only the name ("name:") of the header */
|
|
APT_DECLARE(apt_bool_t) apt_text_header_name_generate(const apt_str_t *name, apt_text_stream_t *text_stream);
|
|
|
|
/** Parse array of name-value pairs */
|
|
APT_DECLARE(apt_bool_t) apt_pair_array_parse(apt_pair_arr_t *arr, const apt_str_t *value, apr_pool_t *pool);
|
|
/** Generate array of name-value pairs */
|
|
APT_DECLARE(apt_bool_t) apt_pair_array_generate(apt_pair_arr_t *arr, apt_text_stream_t *text_stream);
|
|
|
|
|
|
/** Parse boolean-value */
|
|
APT_DECLARE(apt_bool_t) apt_boolean_value_parse(const apt_str_t *str, apt_bool_t *value);
|
|
|
|
/** Generate boolean-value */
|
|
APT_DECLARE(apt_bool_t) apt_boolean_value_generate(apt_bool_t value, apt_text_stream_t *str);
|
|
|
|
|
|
/** Parse size_t value */
|
|
static APR_INLINE apr_size_t apt_size_value_parse(const apt_str_t *str)
|
|
{
|
|
return str->buf ? atol(str->buf) : 0;
|
|
}
|
|
|
|
/** Generate apr_size_t value */
|
|
static APR_INLINE apt_bool_t apt_size_value_generate(apr_size_t value, apt_text_stream_t *stream)
|
|
{
|
|
int length = sprintf(stream->pos, "%"APR_SIZE_T_FMT, value);
|
|
if(length <= 0) {
|
|
return FALSE;
|
|
}
|
|
stream->pos += length;
|
|
return TRUE;
|
|
}
|
|
|
|
/** Parse float value */
|
|
static APR_INLINE float apt_float_value_parse(const apt_str_t *str)
|
|
{
|
|
return str->buf ? (float)atof(str->buf) : 0;
|
|
}
|
|
|
|
/** Generate float value */
|
|
static APR_INLINE apt_bool_t apt_float_value_generate(float value, apt_text_stream_t *stream)
|
|
{
|
|
int length = sprintf(stream->pos,"%.1f",value);
|
|
if(length <= 0) {
|
|
return FALSE;
|
|
}
|
|
stream->pos += length;
|
|
return TRUE;
|
|
}
|
|
|
|
/** Generate string value */
|
|
static APR_INLINE apt_bool_t apt_string_value_generate(const apt_str_t *str, apt_text_stream_t *stream)
|
|
{
|
|
if(str->length) {
|
|
memcpy(stream->pos,str->buf,str->length);
|
|
stream->pos += str->length;
|
|
}
|
|
return TRUE;
|
|
}
|
|
|
|
/** Initialize text stream */
|
|
static APR_INLINE void apt_text_stream_init(apt_text_stream_t *stream, char *buffer, apr_size_t size)
|
|
{
|
|
stream->text.buf = buffer;
|
|
stream->text.length = size;
|
|
stream->pos = stream->text.buf;
|
|
}
|
|
|
|
/** Insert end of the line symbol(s) */
|
|
static APR_INLINE void apt_text_eol_insert(apt_text_stream_t *stream)
|
|
{
|
|
*stream->pos++ = APT_TOKEN_CR;
|
|
*stream->pos++ = APT_TOKEN_LF;
|
|
}
|
|
|
|
/** Insert character */
|
|
static APR_INLINE void apt_text_char_insert(apt_text_stream_t *stream, char ch)
|
|
{
|
|
*stream->pos++ = ch;
|
|
}
|
|
|
|
/** Insert space */
|
|
static APR_INLINE void apt_text_space_insert(apt_text_stream_t *stream)
|
|
{
|
|
*stream->pos++ = APT_TOKEN_SP;
|
|
}
|
|
|
|
/** Skip spaces */
|
|
static APR_INLINE void apt_text_spaces_skip(apt_text_stream_t *stream)
|
|
{
|
|
const char *end = stream->text.buf + stream->text.length;
|
|
while(stream->pos < end && *stream->pos == APT_TOKEN_SP) stream->pos++;
|
|
}
|
|
|
|
/** Skip specified character */
|
|
static APR_INLINE void apt_text_char_skip(apt_text_stream_t *stream, char ch)
|
|
{
|
|
const char *end = stream->text.buf + stream->text.length;
|
|
if(stream->pos < end && *stream->pos == ch) stream->pos++;
|
|
}
|
|
|
|
/** Check whether end of stream is reached */
|
|
static APR_INLINE apt_bool_t apt_text_is_eos(const apt_text_stream_t *stream)
|
|
{
|
|
const char *end = stream->text.buf + stream->text.length;
|
|
return (stream->pos >= end) ? TRUE : FALSE;
|
|
}
|
|
|
|
/** Scroll text stream */
|
|
APT_DECLARE(apt_bool_t) apt_text_stream_scroll(apt_text_stream_t *stream);
|
|
|
|
/** Parse id at resource string */
|
|
APT_DECLARE(apt_bool_t) apt_id_resource_parse(const apt_str_t *str, char separator, apt_str_t *id, apt_str_t *resource, apr_pool_t *pool);
|
|
|
|
/** Generate id at resource string */
|
|
APT_DECLARE(apt_bool_t) apt_id_resource_generate(const apt_str_t *id, const apt_str_t *resource, char separator, apt_str_t *str, apr_pool_t *pool);
|
|
|
|
/** Generate value plus the length (number of digits) of the value itself */
|
|
APT_DECLARE(apt_bool_t) apt_var_length_value_generate(apr_size_t *value, apr_size_t max_count, apt_str_t *str);
|
|
|
|
|
|
/**
|
|
* Generate unique identifier (hex string)
|
|
* @param id the id to generate
|
|
* @param length the length of hex string to generate
|
|
* @param pool the pool to allocate memory from
|
|
*/
|
|
APT_DECLARE(apt_bool_t) apt_unique_id_generate(apt_str_t *id, apr_size_t length, apr_pool_t *pool);
|
|
|
|
|
|
APT_END_EXTERN_C
|
|
|
|
#endif /*__APT_TEXT_STREAM_H__*/
|