Beispiel #1
0
void katana_string_init(struct KatanaInternalParser* parser,
                        KatanaParserString* output) {
    output->data = katana_parser_allocate(parser, kDefaultStringBufferSize);
    memset( output->data, 0, sizeof(kDefaultStringBufferSize) );
    output->length = 0;
    output->capacity = kDefaultStringBufferSize;
}
Beispiel #2
0
static void enlarge_array_if_full(struct KatanaInternalParser* parser,
                                  KatanaArray* array) {
    if (array->length >= array->capacity) {
        if (array->capacity) {
            size_t old_num_bytes = sizeof(void*) * array->capacity;
            array->capacity *= 2;
            size_t num_bytes = sizeof(void*) * array->capacity;
            void** temp = katana_parser_allocate(parser, num_bytes);
            memcpy(temp, array->data, old_num_bytes);
            katana_parser_deallocate(parser, array->data);
            array->data = temp;
        } else {
            // 0-capacity array; no previous array to deallocate.
            array->capacity = 2;
            array->data = katana_parser_allocate(parser, sizeof(void*) * array->capacity);
        }
    }
}
Beispiel #3
0
/**
 * Array
 */
void katana_array_init(struct KatanaInternalParser* parser,
                       size_t initial_capacity, KatanaArray* array) {
    array->length = 0;
    array->capacity = (unsigned int)initial_capacity;
    if (initial_capacity > 0) {
        array->data = katana_parser_allocate(parser, sizeof(void*) * initial_capacity);
    } else {
        array->data = NULL;
    }
}
Beispiel #4
0
const char* katana_string_to_characters(struct KatanaInternalParser * parser, const KatanaParserString* str)
{
    assert(NULL != str);
    if (NULL == str)
        return NULL;
    
    char* buffer = katana_parser_allocate(parser, sizeof(char) * (str->length + 1));
    memcpy(buffer, str->data, str->length);
    buffer[str->length] = '\0';
    return buffer;
}
Beispiel #5
0
const char* katana_string_to_characters_with_prefix_char(struct KatanaInternalParser * parser, const KatanaParserString* str, const char prefix)
{
    assert(str);
    if (NULL == str)
        return NULL;
    
    char* buffer = katana_parser_allocate(parser, sizeof(char) * (str->length + 2));
    memcpy((buffer + 1), str->data, str->length);
    buffer[0] = prefix;
    buffer[str->length] = '\0';
    return buffer;
}
Beispiel #6
0
void katana_string_prepend_characters(struct KatanaInternalParser* parser,
                                      const char* str,
                                      KatanaParserString* output)
{
    size_t len = strlen(str);
    size_t new_length = output->length + len;
    char* new_data = katana_parser_allocate(parser, new_length);
    memcpy(new_data, str, len);
    memcpy(new_data+len, output->data, output->length);
    katana_parser_deallocate(parser, output->data);
    output->data = new_data;
    output->length = new_length;
    output->capacity = new_length;
}
Beispiel #7
0
static void maybe_resize_string(struct KatanaInternalParser* parser,
                                size_t additional_chars,
                                KatanaParserString* str) {
    size_t new_length = str->length + additional_chars;
    size_t new_capacity = str->capacity;
    while (new_capacity < new_length) {
        new_capacity *= 2;
    }
    if (new_capacity != str->capacity) {
        char* new_data = katana_parser_allocate(parser, new_capacity);
        memset(new_data, 0, str->length);
        memcpy(new_data, str->data, str->length);
        katana_parser_deallocate(parser, str->data);
        str->data = new_data;
        str->capacity = new_capacity;
    }
}
Beispiel #8
0
KatanaParserString* katana_selector_to_string(KatanaParser* parser, KatanaSelector* selector, KatanaParserString* next)
{
    KatanaParserString* string = katana_parser_allocate(parser, sizeof(KatanaParserString));
    katana_string_init(parser, string);
    
    bool tag_is_implicit = true;
    
    if (selector->match == KatanaSelectorMatchTag && tag_is_implicit)
    {
        if ( NULL == selector->tag->prefix )
            katana_string_append_characters(parser, selector->tag->local, string);
        else {
            katana_string_append_characters(parser, selector->tag->prefix, string);
            katana_string_append_characters(parser, "|", string);
            katana_string_append_characters(parser, selector->tag->local, string);
        }
    }

    const KatanaSelector* cs = selector;

    while (true) {
        if (cs->match == KatanaSelectorMatchId) {
            katana_string_append_characters(parser, "#", string);
            katana_string_append_characters(parser, cs->data->value, string);
        } else if (cs->match == KatanaSelectorMatchClass) {
            katana_string_append_characters(parser, ".", string);
            katana_string_append_characters(parser, cs->data->value, string);
        } else if (cs->match == KatanaSelectorMatchPseudoClass || cs->match == KatanaSelectorMatchPagePseudoClass) {
            katana_string_append_characters(parser, ":", string);
            katana_string_append_characters(parser, cs->data->value, string);
            
            switch (cs->pseudo) {
                case KatanaPseudoAny:
                case KatanaPseudoNot:
                case KatanaPseudoHost:
                case KatanaPseudoHostContext: {
                    if ( cs->data->selectors ) {
                        KatanaArray* sels = cs->data->selectors;
                        for (size_t i=0; i<sels->length; i++) {
                            KatanaParserString* str = katana_selector_to_string(parser, sels->data[i], NULL);
                            katana_string_append_string(parser, str, string);
                            katana_parser_deallocate(parser, (void*) str->data);
                            katana_parser_deallocate(parser, (void*) str);
                            if ( i != sels->length -1 ) {
                                katana_string_append_characters(parser, ", ", string);
                            }
                        }
                        katana_string_append_characters(parser, ")", string);
                    }
                }
                    break;
                case KatanaPseudoLang:
                case KatanaPseudoNthChild:
                case KatanaPseudoNthLastChild:
                case KatanaPseudoNthOfType:
                case KatanaPseudoNthLastOfType: {
                    katana_string_append_characters(parser, cs->data->argument, string);
                    katana_string_append_characters(parser, ")", string);
                }
                    break;
                default:
                    break;
            }
        } else if (cs->match == KatanaSelectorMatchPseudoElement) {
            katana_string_append_characters(parser, "::", string);
            katana_string_append_characters(parser, cs->data->value, string);
        } else if (katana_selector_is_attribute(cs)) {
            katana_string_append_characters(parser, "[", string);
            if (NULL != cs->data->attribute->prefix) {
                katana_string_append_characters(parser, cs->data->attribute->prefix, string);
                katana_string_append_characters(parser, "|", string);
            }
            katana_string_append_characters(parser, cs->data->attribute->local, string);
            switch (cs->match) {
                case KatanaSelectorMatchAttributeExact:
                    katana_string_append_characters(parser, "=", string);
                    break;
                case KatanaSelectorMatchAttributeSet:
                    katana_string_append_characters(parser, "]", string);
                    break;
                case KatanaSelectorMatchAttributeList:
                    katana_string_append_characters(parser, "~=", string);
                    break;
                case KatanaSelectorMatchAttributeHyphen:
                    katana_string_append_characters(parser, "|=", string);
                    break;
                case KatanaSelectorMatchAttributeBegin:
                    katana_string_append_characters(parser, "^=", string);
                    break;
                case KatanaSelectorMatchAttributeEnd:
                    katana_string_append_characters(parser, "$=", string);
                    break;
                case KatanaSelectorMatchAttributeContain:
                    katana_string_append_characters(parser, "*=", string);
                    break;
                default:
                    break;
            }
            if (cs->match != KatanaSelectorMatchAttributeSet) {
                katana_string_append_characters(parser, "\"", string);
                katana_string_append_characters(parser, cs->data->value, string);
                katana_string_append_characters(parser, "\"", string);
                if (cs->data->bits.attributeMatchType == KatanaAttributeMatchTypeCaseInsensitive)
                    katana_string_append_characters(parser, " i", string);
                katana_string_append_characters(parser, "]", string);
            }
        }
        if (cs->relation != KatanaSelectorRelationSubSelector || !cs->tagHistory)
            break;
        cs = cs->tagHistory;
    }

    KatanaSelector* tagHistory = cs->tagHistory;

    if ( NULL != tagHistory ) {
        switch (cs->relation) {
            case KatanaSelectorRelationDescendant:
            {
                return katana_build_relation_selector_string(parser, " ", string, next, tagHistory);
            }
            case KatanaSelectorRelationChild:
            {
                return katana_build_relation_selector_string(parser, " > ", string, next, tagHistory);
            }
            case KatanaSelectorRelationShadowDeep:
            {
                return katana_build_relation_selector_string(parser, " /deep/ ", string, next, tagHistory);
            }
            case KatanaSelectorRelationDirectAdjacent:
            {
                return katana_build_relation_selector_string(parser, " + ", string, next, tagHistory);
            }
            case KatanaSelectorRelationIndirectAdjacent:
            {
                return katana_build_relation_selector_string(parser, " ~ ", string, next, tagHistory);
            }
            case KatanaSelectorRelationSubSelector:
            {
                return NULL;
            }
            case KatanaSelectorRelationShadowPseudo:
            {
                return katana_build_relation_selector_string(parser, NULL, string, next, tagHistory);
            }
        }
    }
    
    if ( NULL != next ) {
        katana_string_append_string(parser, (KatanaParserString*)next, string);
    }
    
    return (KatanaParserString*)string;
}