Exemplo n.º 1
0
ch8 *
buf_text(Buf *buffer, memi offset, memi size, ch8 *out)
{
    requirement_check_buf(buffer);

    hale_assert_requirement(size <= buf_capacity);
    hale_assert_requirement(size <= buf_length(buffer));
    hale_assert_requirement(offset <= buf_capacity);
    hale_assert_requirement(offset <= buf_length(buffer));
    hale_assert_requirement((offset + size) <= buf_length(buffer));

    ch8 *begin = buf_page_begin(buffer);
    ch8 *ptr = begin + offset;

    if (ptr >= buffer->gap_start)
    {
        //     .....#####..|xxx
        //     vvv----------^^^
        // out xxx

        platform.copy_memory(out, ptr + buf_gap(buffer), size);
        out += size;
    }
    else if ((ptr + size) <= buffer->gap_start)
    {
        //     .|xxx.#####.....
        //     vvI^^
        // out xxx

        platform.copy_memory(out, ptr, size);
        out += size;
    }
    else
    {
        //     ...|xx#####x....
        //     vv--^^
        // out xx

#if HALE_DEBUG
        memi p = size;
#endif
        memi s = buffer->gap_start - ptr;
        platform.copy_memory(out, ptr, s);
        hale_debug(p -= s);

        //     ...|xx#####o....
        //       v--------^
        // out xxo

        out += s;
        platform.copy_memory(out,
                             buffer->gap_end,
                             size - s);
        out += (size-s);
        hale_debug(p -= (size-s));
        hale_assert_debug(p == 0);
    }

    return out;
}
Exemplo n.º 2
0
void
fixed_gap_arena_insert(FixedGapArena *arena,
                       memi offset,
                       const ch8 *data,
                       memi size)
{
    // TODO: In case we can take ownership of data, we can just wrap it with gap buffers and be done.
    // TODO: In case we cannot take ownership of data, but the data is persistent, we can wrap it with copy-on-write gap buffers.

    // TODO: Remove the checks.
    if (size == 0) {
        return;
    }
    hale_assert(offset <= arena->size);
    hale_assert_debug(vector_count(arena->buffers));

    Buf *it0 = find_buf_GTE(arena,
                       &offset,
                       vector_begin(&arena->buffers),
                       vector_end(&arena->buffers));

    // Move these to tests.
    hale_assert_requirement(it0);
    // hale_assert(buf_length(it) != 0);
    hale_assert(buf_length(it0) >= offset);

    if (buf_available(it0) >= size) {
        buf_insert(it0, offset, data, size);
    } else {
        insert_non_crit_branch(arena, offset, data, size, it0);
    }

    arena->size += size;
}
Exemplo n.º 3
0
static void act_paste (void) {
    fileoffset_t cutsize, new_top;

    if (!cutbuffer)
	return;
    cutsize = buf_length (cutbuffer);
    if (!insert_mode) {
	if (cur_pos + cutsize > file_size) {
	    display_beep();
	    strcpy (message, "Too close to end of file to paste");
	    return;
	}
	buf_delete (filedata, cutsize, cur_pos);
	file_size -= cutsize;
    }
    buf_paste (filedata, cutbuffer, cur_pos);
    modified = TRUE;
    cur_pos += cutsize;
    file_size += cutsize;
    edit_type = !!edit_type;
    new_top = cur_pos - (scrlines-1) * width;
    if (new_top < 0)
	new_top = 0;
    new_top = begline(new_top);
    if (top_pos < new_top)
	top_pos = new_top;
}
Exemplo n.º 4
0
// Prepares the HTTP page.
static void
prepare_page(struct http_state *hs)
{
    hs->buf[0] = '\0';
    buf_append_text(hs->buf, "HTTP/1.0 200 OK\r\n");
    buf_append_text(hs->buf, "Content-Type: text/html\r\n");
    buf_append_text(hs->buf, "\r\n");
    buf_append_text(hs->buf, "<html>\r\n");
    buf_append_text(hs->buf, "<h1>eCos - HTTP test server running on lwIP</h1>\r\n");
    buf_append_text(hs->buf, "<table><tr><td>Version:</td><td>");
    buf_append_dec(hs->buf, LWIP_VERSION_MAJOR);
    buf_append_text(hs->buf, ".");
    buf_append_dec(hs->buf, LWIP_VERSION_MINOR);
    buf_append_text(hs->buf, ".");
    buf_append_dec(hs->buf, LWIP_VERSION_REVISION);
    if (LWIP_VERSION_IS_RELEASE)
        buf_append_text(hs->buf, " (release)");
    if (LWIP_VERSION_IS_DEVELOPMENT)
        buf_append_text(hs->buf, " (development)");
    if (LWIP_VERSION_IS_RC)
        buf_append_text(hs->buf, " (rc)");
    buf_append_text(hs->buf, "</td></tr><tr><td>Requests:</td><td>");
    buf_append_dec(hs->buf, request_counter++);
    buf_append_text(hs->buf, "</td></tr></table>\r\n");
    buf_append_text(hs->buf, "</html>");
    
    hs->file = hs->buf;
    hs->left = buf_length(hs->buf);
}
Exemplo n.º 5
0
hale_internal
Buf *
find_buf_GT(FixedGapArena *arena, memi *offset, Buf *begin, Buf *end)
{
    Buf *it = begin;
    memi o = 0;
    while (it != end)
    {
        o += buf_length(it);
        if (o > *offset) {
            *offset -= (o - buf_length(it));
            return it;
        }
        ++it;
    }
    return NULL;
}
Exemplo n.º 6
0
ch8 *
fixed_gap_arena_text(FixedGapArena *arena, memi offset, memi size, ch8 *out)
{
    hale_assert(offset <= arena->size);
    hale_assert(size <= arena->size);
    hale_assert(offset + size <= arena->size);
    if (size == 0) {
        return out;
    }

    Buf *it = &vector_first(&arena->buffers);
    Buf *end = it + vector_count(arena->buffers);
    it = find_buf_GT(arena, &offset, it, end);

#if HALE_DEBUG
    ch8 *out_end = out + size;
#endif

    // Protected by asserts above.
    hale_assert_requirement(it != end);

    memi s = buf_length(it);
    s = hale_minimum(size, s - offset);
    out = buf_text(it, offset, s, out);
    hale_assert_debug(out <= out_end);
    size -= s;

    while (size)
    {
        ++it;
        s = hale_minimum(size, buf_length(it));
        out = buf_text(it, 0, s, out);
        hale_assert_debug(out <= out_end);
        size -= s;
    }

    return out;
}
Exemplo n.º 7
0
void
fixed_gap_arena_remove(FixedGapArena *arena, memi offset, memi size)
{
    // TODO: Decide how much we want to protect the API.
    //       This one is public, so maybe allow more protection?
    if (size == 0) {
        return;
    }

    hale_assert_input((offset + size) <= arena->size);
    hale_assert_input(offset <= arena->size);

    Buf *it0 = vector_begin(&arena->buffers);
    Buf *end = vector_end(&arena->buffers);
    it0 = find_buf_GT(arena, &offset, it0, end);
    hale_assert_requirement(it0 != end);

    memi length = buf_length(it0);
    if ((offset + size) < length)
    {
        buf_remove(it0, offset, size);
    }
    else
    {
        memi p2 = size;

        if (offset != 0)
        {
            p2 -= buf_remove(it0, offset, length - offset);
            ++it0;
        }

        if (p2)
        {
            Buf *itE = it0;
            length = buf_length(it0);

            if (p2 == length)
            {
                p2 = 0;
                ++itE;
            }
            else // if (p2)
            {
                while (length < p2)
                {
                    p2 -= length;
                    ++itE;
                    if (itE == end) {
                        break;
                    }
                    length = buf_length(itE);
                }

                if (p2) {
                    buf_remove(itE, 0, p2);
                }
            }


            if (it0 != itE) {
                if (vector_count(&arena->buffers) == 1) {
                    // Do not remove the first buffer.
                    // Requirement for `insert`.
                    buf_clear(it0);
                } else {
                    vector_remove(&arena->buffers, it0, itE);
                }
            }
        }
    }

    arena->size -= size;
}
Exemplo n.º 8
0
hale_internal
void
insert_non_crit_branch(FixedGapArena *arena,
                       memi offset,
                       const ch8 *data,
                       memi size,
                       Buf *it0)
{
    requirement_check_buf(it0);

    Buf *it1 = NULL;

    // TODO: Merge the `it` with next and previous buffers.

    // [...**]
    //     ^^----suffix----vv
    // [..+++] [+++++] [+++**]
    //    ^^^   ^^^^^   ^^^
    //    +++   +++++   +++**
    //    p0      p1     p2 ^-sx

    // http://cpp.sh/9yp22

    // Copy to first (possible split)
    memi p0 = hale_minimum(buf_capacity - offset, size);
    // Copy to new buffers (full)
    memi p1 = (size-p0) & ~buf_align_mask;
    // Copy to last (partial)
    memi p2 = (size-p0) &  buf_align_mask; // same as (data_size - r.p1 - r.p0);
    // Split size (won't underflow, as offset must be within the block (or == buf_length))
    memi sx = buf_length(it0) - offset;

    hale_assert(p0 + p1 + p2 == size);

    // TODO: Check if we can put part of `p1`, `p2` into sx.
    // - `p1` probably makes no sense to be merged with sx, as it's already calculated to be full.

    memi n = 0;
    // if (p0 && sx) { n += 1; }
    n += p0 && sx;
    // if (p1)       { n += p1 >> buf_capacity_shift; }
    n += p1 >> buf_align_shift;
    // if (p2)       { n += 1; }
    n += !!p2;

    if (n) {
        it1 = allocate_buffers(arena, buf_index(arena, it0) + 1, n);
        // TODO: This wouldn't be needed if allocate_buffers wouldn't
        // invalidate the pointers. (deque?)
        it0 = it1 - 1;
    }

    if (p0) {
        if (sx) {
            hale_assert_requirement(n != 0)
            buf_move_suffix(it0, offset, it0 + n); // same as `it1 + n - 1`
        }
        buf_insert(it0, offset, data, p0);

        // `data` and `size` is used in `p1` and `p2`,
        // so we update he right away.
        data += p0;
        size -= p0;
    }

    if (p1)
    {
        hale_assert_debug(it1);

        while (size != p2)
        {
            // TODO: buf_set
            buf_insert(it1, 0, data, buf_capacity);
            data += buf_capacity;
            size -= buf_capacity;
            ++it1;
        }
    }

    if (p2) {
        hale_assert_requirement(it1);
        hale_assert_requirement(p2 == size);
        // TODO: buf_set
        buf_insert(it1, 0, data, p2);
    }
}
Exemplo n.º 9
0
void
buf_move_suffix(Buf *A, memi offset, Buf *B)
{
    requirement_check_buf(A);
    requirement_check_buf(B);

    hale_assert_requirement(buf_length(A) != 0);
    hale_assert_requirement(offset < buf_length(A));

#if HALE_REQUIREMENT
    ch8 *B_page = buf_page_begin(B);
    ch8 *A_page = buf_page_begin(A);
#endif

    ch8 *A_ptr = buf_page_begin(A) + offset;
    // ch8 *B_ptr = buf_page_begin(B);
    B->gap_start = buf_page_begin(B);
    B->gap_end = buf_page_end(B);
    hale_debug(B->debug_length = 0);

    memi s;

    if (A_ptr >= A->gap_start)
    {
        // A .....#####..|xxx
        //        vv---^^
        // A .......#####|xxx

        A_ptr += buf_gap(A);

        s = A_ptr - A->gap_end;

        if (s) {
            platform.move_memory(A->gap_start, A->gap_end, s);
//            A->gap_start += s;
//#if HALE_REQUIREMENT
//        A->gap_end += s;
//#endif
        }


        // A .......#####|xxx
        //   vvv----------^^^
        // B xxx#############

        s = buf_length(A) - offset;
        platform.copy_memory(B->gap_start, A_ptr, s);
        B->gap_start += s;
        hale_debug(B->debug_length += s);
        hale_debug(A->debug_length -= s);
        A->gap_start = A_ptr - buf_gap(A);
        A->gap_end = buf_page_end(A);

//#if HALE_REQUIREMENT
//        A->gap_end += s;
//#else
//        A->gap_end = buf_page_end(A);
//#endif
    }
    else // if(A_ptr < A->gap_start)
    {
        hale_assert_requirement(A_ptr < A->gap_start);

        // A ..ooo#####xxxxx
        //   v-^^^
        // B ooo############

        s = A->gap_start - A_ptr;
        platform.copy_memory(B->gap_start, A_ptr, s);
        B->gap_start += s;
        hale_debug(B->debug_length += s);
        hale_debug(A->debug_length -= s);

        // A ..ooo#####xxxxx
        //      vvvvv--^^^^^
        // B oooxxxxx#######

        s = buf_page_end(A) - A->gap_end;
        if (s) {
            platform.copy_memory(B->gap_start, A->gap_end, s);
            B->gap_start += s;
            hale_debug(B->debug_length += s);
            hale_debug(A->debug_length -= s);
        }

        A->gap_start = A_ptr;
        A->gap_end += s;
    }

    hale_assert_requirement(A->gap_start == buf_page_begin(A) + offset);
    hale_assert_requirement(A->gap_end == buf_page_end(A));
    hale_assert_requirement(((memi)A->gap_start &~ buf_align_mask)
                         == ((memi)A_ptr &~ buf_align_mask));

    // B->gap_end is always at the end.
    if (B->gap_start == B->gap_end) {
        // Special case, when we always reset the buffer to be at the beginning once it's full.
        // In this case we're sure that we will never move
        B->gap_start = B->gap_end = (ch8*)((memi)(B->gap_end - 1) & ~buf_align_mask);
    }

    hale_assert_requirement(buf_page_begin(A) == A_page);
    hale_assert_requirement(buf_page_begin(B) == B_page);

    requirement_check_buf(A);
    requirement_check_buf(B);
}
Exemplo n.º 10
0
memi
buf_remove(Buf *buffer, memi offset, memi size)
{
    hale_assert(size <= buf_length(buffer));
    hale_assert(offset <= buf_length(buffer));
    hale_assert((offset + size) <= buf_length(buffer));
    requirement_check_buf(buffer);

    ch8 *begin = buf_page_begin(buffer) + offset;
    ch8 *end   = buf_page_begin(buffer) + offset + size;

    memi s;
    // No gap
    if (buffer->gap_end == buffer->gap_start)
    {
        buffer->gap_start = begin;
        buffer->gap_end = end;
    }
    // Before gap
    else if (begin <= buffer->gap_start && end <= buffer->gap_start)
    {
        // .xx..###########
        //  vv^^
        // ...#############

        // .xxx.#####.....
        //  v--^
        // ..#########.....

        s = buf_move(buffer,
                     end, buffer->gap_start,
                     begin);

        buffer->gap_start = begin + s;
    }
    // Around the gap
    else if (begin <= buffer->gap_start)
    {
        // ..[..]#####.....
        // ..#########.....

        // ..[...#####...]..
        // ..#############..

        // ......[#####...]..
        // ......##########..

        // ......#####[...]..
        // ......##########..

        buffer->gap_end = hale_maximum(end + buf_gap(buffer), buffer->gap_end);
        // Must be done after calling `buf_gap`. Idiot.
        buffer->gap_start = begin;
    }
    // After the gap
    else if(begin > buffer->gap_start && end > buffer->gap_start)
    {
        // ......#####.[..]..
        //       v----^
        // .......#########..
        begin += buf_gap(buffer);
        end   += buf_gap(buffer);

        s = buf_move(buffer,
                     buffer->gap_end, begin,
                     buffer->gap_start);

        buffer->gap_start += s;
        buffer->gap_end = end;
    }

    hale_debug(buffer->debug_length -= size);
    requirement_check_buf(buffer);

    return size;
}