/* ChibiOS - Copyright (C) 2006..2016 Giovanni Di Sirio. This file is part of ChibiOS. ChibiOS is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3 of the License, or (at your option) any later version. ChibiOS is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ /** * @file chheap.c * @brief Heaps code. * * @addtogroup heaps * @details Heap Allocator related APIs. *

Operation mode

* The heap allocator implements a first-fit strategy and its APIs * are functionally equivalent to the usual @p malloc() and @p free() * library functions. The main difference is that the OS heap APIs * are guaranteed to be thread safe and there is the ability to * return memory blocks aligned to arbitrary powers of two.
* @pre In order to use the heap APIs the @p CH_CFG_USE_HEAP option must * be enabled in @p chconf.h. * @note Compatible with RT and NIL. * @{ */ #include "ch.h" #if (CH_CFG_USE_HEAP == TRUE) || defined(__DOXYGEN__) /*===========================================================================*/ /* Module local definitions. */ /*===========================================================================*/ /* * Defaults on the best synchronization mechanism available. */ #if (CH_CFG_USE_MUTEXES == TRUE) || defined(__DOXYGEN__) #define H_LOCK(h) chMtxLock(&(h)->mtx) #define H_UNLOCK(h) chMtxUnlock(&(h)->mtx) #else #define H_LOCK(h) (void) chSemWait(&(h)->sem) #define H_UNLOCK(h) chSemSignal(&(h)->sem) #endif #define H_BLOCK(hp) ((hp) + 1U) #define H_LIMIT(hp) (H_BLOCK(hp) + H_PAGES(hp)) #define H_NEXT(hp) ((hp)->free.next) #define H_PAGES(hp) ((hp)->free.pages) #define H_HEAP(hp) ((hp)->used.heap) #define H_SIZE(hp) ((hp)->used.size) /* * Number of pages between two pointers in a MISRA-compatible way. */ #define NPAGES(p1, p2) \ /*lint -save -e9033 [10.8] The cast is safe.*/ \ ((size_t)((p1) - (p2))) \ /*lint -restore*/ /*===========================================================================*/ /* Module exported variables. */ /*===========================================================================*/ /*===========================================================================*/ /* Module local types. */ /*===========================================================================*/ /*===========================================================================*/ /* Module local variables. */ /*===========================================================================*/ /** * @brief Default heap descriptor. */ static memory_heap_t default_heap; /*===========================================================================*/ /* Module local functions. */ /*===========================================================================*/ /*===========================================================================*/ /* Module exported functions. */ /*=================
"""
This inline script modifies a streamed response.
If you do not need streaming, see the modify_response_body example.
Be aware that content replacement isn't trivial:
    - If the transfer encoding isn't chunked, you cannot simply change the content length.
    - If you want to replace all occurrences of "foobar", make sure to catch the cases
      where one chunk ends with [...]foo" and the next starts with "bar[...].
"""


def modify(chunks):
    """
    chunks is a generator that can be used to iterate over all chunks.
    """
    for chunk in chunks:
        yield chunk.replace("foo", "bar")


def responseheaders(flow):
    flow.response.stream = modify
the total * fragmented free space or @ NULL * @param[in] largestp pointer to a variable that will receive the largest * free free block found space or @ NULL * @return The number of fragments in the heap. * * @api */ size_t chHeapStatus(memory_heap_t *heapp, size_t *totalp, size_t *largestp) { heap_header_t *qp; size_t n, tpages, lpages; if (heapp == NULL) { heapp = &default_heap; } H_LOCK(heapp); tpages = 0U; lpages = 0U; n = 0U; qp = &heapp->header; while (H_NEXT(qp) != NULL) { size_t pages = H_PAGES(H_NEXT(qp)); /* Updating counters.*/ n++; tpages += pages; if (pages > lpages) { lpages = pages; } qp = H_NEXT(qp); } /* Writing out fragmented free memory.*/ if (totalp != NULL) { *totalp = tpages * CH_HEAP_ALIGNMENT; } /* Writing out unfragmented free memory.*/ if (largestp != NULL) { *largestp = lpages * CH_HEAP_ALIGNMENT; } H_UNLOCK(heapp); return n; } #endif /* CH_CFG_USE_HEAP == TRUE */ /** @} */