/* Add a new current_block to the Blocks* chain, adjust size if nbytes big. */
static void
add_block(Blocks *blocks, int nbytes)
{
    int header_size;
    int block_size;
    BlockHeader *block_header;

    HPROF_ASSERT(blocks!=NULL);
    HPROF_ASSERT(nbytes>0);

    header_size          = real_size(blocks->alignment, sizeof(BlockHeader));
    block_size           = blocks->elem_size*blocks->population;
    if ( nbytes > block_size ) {
        block_size = real_size(blocks->alignment, nbytes);
    }
    block_header         = (BlockHeader*)HPROF_MALLOC(block_size+header_size);
    block_header->next   = NULL;
    block_header->bytes_left = block_size;
    block_header->next_pos   = header_size;

    /* Link in new block */
    if ( blocks->current_block != NULL ) {
        blocks->current_block->next = block_header;
    }
    blocks->current_block = block_header;
    if ( blocks->first_block == NULL ) {
        blocks->first_block = block_header;
    }
}
    static size_t onWrite(char *ptr, size_t size, size_t nmemb, void *userdata)
    {
        WebRequestInternalState *is_(reinterpret_cast<WebRequestInternalState*>(userdata));
        is_->state = HTTP_OPEN;
        if (is_->isAborted)
        {
            is_->state = HTTP_CLOSED;
            // This should probably be CURL_WRITEFUNC_ABORT, but that doesn't
            // exist. It probably would be the same numeric value, if it did.
            // The docs say that it just has to be a number of bytes that is
            // not "size * nmemb" to abort.
            return CURL_READFUNC_ABORT;
        }

        // Find the size in bytes.
        size_t real_size(size * nmemb);

        // Write the date into the download buffer queue.
        Serializer* download(dynamic_cast<Serializer*>(is_->download.Get()));
        download->Write(ptr, (unsigned int)real_size);

        // Emit a "download_chunk" event.
        VariantMap eventData;
        eventData.Insert(MakePair(StringHash("download"), Variant(is_->download)));
        eventData.Insert(MakePair(StringHash("size"), Variant((unsigned int)real_size)));
        is_->es.SendEvent("download_chunk", eventData);

        return real_size;
    }
/* Allocate bytes from a Blocks area. */
void *
blocks_alloc(Blocks *blocks, int nbytes)
{
    BlockHeader *block;
    int   pos;
    void *ptr;

    HPROF_ASSERT(blocks!=NULL);
    HPROF_ASSERT(nbytes>=0);
    if ( nbytes == 0 ) {
        return NULL;
    }

    block = blocks->current_block;
    nbytes = real_size(blocks->alignment, nbytes);
    if ( block == NULL || block->bytes_left < nbytes ) {
        add_block(blocks, nbytes);
        block = blocks->current_block;
    }
    pos = block->next_pos;
    ptr = (void*)(((char*)block)+pos);
    block->next_pos   += nbytes;
    block->bytes_left -= nbytes;
    return ptr;
}
    static size_t onRead(char *buffer, size_t size, size_t nitems, void *instream)
    {
        WebRequestInternalState *is_(reinterpret_cast<WebRequestInternalState*>(instream));
        is_->state = HTTP_OPEN;
        if (is_->isAborted)
        {
            is_->state = HTTP_CLOSED;
            return CURL_READFUNC_ABORT;
        }

        // Find the size in bytes.
        size_t real_size(size * nitems);

        // Read as much as we can from the upload buffer queue.
        Deserializer* upload(dynamic_cast<Deserializer*>(is_->upload.Get()));
        size_t size_queued(upload->GetSize());
        size_t size_left(real_size);
        if ((size_left > 0) && (size_queued > 0))
        {
            size_t read_size(std::min(size_queued, size_left));
            upload->Read(buffer, (unsigned int)read_size);
            size_left -= read_size;
        }

        // If we still have bytes to fill, then emit a "upload_chunk" event.
        if (size_left > 0)
        {
            VariantMap eventData;
            eventData.Insert(MakePair(StringHash("upload"), Variant(is_->upload)));
            eventData.Insert(MakePair(StringHash("size"), Variant((unsigned int)size_left)));
            is_->es.SendEvent("upload_chunk", eventData);
        }

        // Read as much as we can from the upload buffer queue (again).
        size_queued = upload->GetSize();
        size_left = real_size;
        if ((size_left > 0) && (size_queued > 0))
        {
            size_t read_size(std::min(size_queued, size_left));
            upload->Read(buffer, (unsigned int)read_size);
            size_left -= read_size;
        }

        // If we still have bytes to fill, then something went wrong, so we should abort.
        if (size_left > 0)
        {
            is_->isAborted = true;
            return CURL_READFUNC_ABORT;
        }

        return real_size;
    }
    static size_t onHeader(char *ptr, size_t size, size_t nmemb, void *userdata)
    {
        WebRequestInternalState *is_(reinterpret_cast<WebRequestInternalState*>(userdata));
        if (is_->isAborted)
        {
            is_->state = HTTP_CLOSED;
            // This should probably be CURL_HEADERFUNC_ABORT, but that doesn't
            // exist. It probably would be the same numeric value, if it did.
            // The docs say that it just has to be a number of bytes that is
            // not "size * nmemb" to abort.
            return CURL_READFUNC_ABORT;
        }

        // Find the size in bytes.
        size_t real_size(size * nmemb);

        // Check for some known values.
        if (real_size == 2 && ptr[0] == '\r' && ptr[1] == '\n')
        {
            return real_size;
        }
        if (real_size > 5 && !strncmp(ptr, "HTTP/", 5))
        {
            return real_size;
        }

        // Get the header key and value, and add them to the map.
        unsigned int key_end = 0;
        unsigned int value_begin = 2;
        while (value_begin < real_size)
        {
            if (ptr[key_end] == ':' && ptr[key_end + 1] == ' ')
            {
                break;
            }
            ++key_end;
            ++value_begin;
        }
        if (value_begin == real_size)
        {
            String key(ptr, (unsigned int)real_size);
            is_->responseHeaders.InsertNew(key.ToUpper(), MakePair(key, String()));
        }
        else
        {
            String key(ptr, (unsigned int)key_end);
            is_->responseHeaders.InsertNew(key.ToUpper(), MakePair(key, String(ptr + value_begin, (unsigned int)real_size - value_begin - 2)));
        }

        return real_size;
    }
Beispiel #6
0
template<typename T> SegmentTree<T>::SegmentTree(   NVector size,
                                                    T (*f)(T,T),
                                                    T zero_element,
                                                    bool sparse):
    dim(size.dim),
    operation(f),
    SIZE(real_size(size)),
    zero(zero_element){

    if(!sparse)
        data=new DenseNArray<T>(2*SIZE,zero_element);
    else
        data=new SparseNArray<T>(2*SIZE,zero_element);
}