zoukankan      html  css  js  c++  java
  • C language description

    16.  bit

    bits.c

    /*
     * Copyright (C) 2018 Swift Navigation Inc.
     * Contact: Swift Navigation <dev@swiftnav.com>
     *
     * This source is subject to the license found in the file 'LICENSE' which must
     * be distributed together with this source. All other rights reserved.
     *
     * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
     * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
     * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
     */
    
    #include <rtcm3/bits.h>
    
    /** Get bit field from buffer as an unsigned integer.
     * Unpacks `len` bits at bit position `pos` from the start of the buffer.
     * Maximum bit field length is 32 bits, i.e. `len <= 32`.
     *
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * 
    eturn Bit field as an unsigned value.
     */
    uint32_t rtcm_getbitu(const uint8_t *buff, uint32_t pos, uint8_t len) {
      uint32_t bits = 0;
    
      for (uint32_t i = pos; i < pos + len; i++) {
        bits = (bits << 1) + ((buff[i / 8] >> (7 - i % 8)) & 1u);
      }
    
      return bits;
    }
    
    /** Get bit field from buffer as an unsigned long integer.
     * Unpacks `len` bits at bit position `pos` from the start of the buffer.
     * Maximum bit field length is 64 bits, i.e. `len <= 64`.
     *
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * 
    eturn Bit field as an unsigned value.
     */
    uint64_t rtcm_getbitul(const uint8_t *buff, uint32_t pos, uint8_t len) {
      uint64_t bits = 0;
    
      for (uint32_t i = pos; i < pos + len; i++) {
        bits = (bits << 1) + ((buff[i / 8] >> (7 - i % 8)) & 1u);
      }
    
      return bits;
    }
    
    /** Get bit field from buffer as a signed integer.
     * Unpacks `len` bits at bit position `pos` from the start of the buffer.
     * Maximum bit field length is 32 bits, i.e. `len <= 32`.
     *
     * This function sign extends the `len` bit field to a signed 32 bit integer.
     *
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * 
    eturn Bit field as a signed value.
     */
    int32_t rtcm_getbits(const uint8_t *buff, uint32_t pos, uint8_t len) {
      int32_t bits = (int32_t)rtcm_getbitu(buff, pos, len);
    
      /* Sign extend, taken from:
       * http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend
       */
      int32_t m = 1u << (len - 1);
      return (bits ^ m) - m;
    }
    
    /** Get bit field from buffer as a signed integer.
     * Unpacks `len` bits at bit position `pos` from the start of the buffer.
     * Maximum bit field length is 64 bits, i.e. `len <= 64`.
     *
     * This function sign extends the `len` bit field to a signed 64 bit integer.
     *
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * 
    eturn Bit field as a signed value.
     */
    int64_t rtcm_getbitsl(const uint8_t *buff, uint32_t pos, uint8_t len) {
      int64_t bits = (int64_t)rtcm_getbitul(buff, pos, len);
    
      /* Sign extend, taken from:
       * http://graphics.stanford.edu/~seander/bithacks.html#VariableSignExtend
       */
      int64_t m = ((uint64_t)1) << (len - 1);
      return (bits ^ m) - m;
    }
    
    /** Set bit field in buffer from an unsigned integer.
     * Packs `len` bits into bit position `pos` from the start of the buffer.
     * Maximum bit field length is 32 bits, i.e. `len <= 32`.
     *
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * param data Unsigned integer to be packed into bit field.
     */
    void rtcm_setbitu(uint8_t *buff, uint32_t pos, uint32_t len, uint32_t data) {
      uint32_t mask = 1u << (len - 1);
    
      if (len <= 0 || 32 < len) {
        return;
      }
    
      for (uint32_t i = pos; i < pos + len; i++, mask >>= 1) {
        if (data & mask) {
          buff[i / 8] |= 1u << (7 - i % 8);
        } else {
          buff[i / 8] &= ~(1u << (7 - i % 8));
        }
      }
    }
    
    /** Set bit field in buffer from an unsigned integer.
     * Packs `len` bits into bit position `pos` from the start of the buffer.
     * Maximum bit field length is 64 bits, i.e. `len <= 64`.
     *
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * param data Unsigned integer to be packed into bit field.
     */
    void rtcm_setbitul(uint8_t *buff, uint32_t pos, uint32_t len, uint64_t data) {
      uint64_t mask = ((uint64_t)1) << (len - 1);
    
      if (len <= 0 || 64 < len) {
        return;
      }
    
      for (uint32_t i = pos; i < pos + len; i++, mask >>= 1) {
        if (data & mask) {
          buff[i / 8] |= ((uint64_t)1) << (7 - i % 8);
        } else {
          buff[i / 8] &= ~(((uint64_t)1) << (7 - i % 8));
        }
      }
    }
    
    /** Set bit field in buffer from a signed integer.
     * Packs `len` bits into bit position `pos` from the start of the buffer.
     * Maximum bit field length is 32 bits, i.e. `len <= 32`.
     *
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * param data Signed integer to be packed into bit field.
     */
    void rtcm_setbits(uint8_t *buff, uint32_t pos, uint32_t len, int32_t data) {
      rtcm_setbitu(buff, pos, len, (uint32_t)data);
    }
    
    /** Set bit field in buffer from a signed integer.
     * Packs `len` bits into bit position `pos` from the start of the buffer.
     * Maximum bit field length is 32 bits, i.e. `len <= 32`.
     *
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * param data Signed integer to be packed into bit field.
     */
    void rtcm_setbitsl(uint8_t *buff, uint32_t pos, uint32_t len, int64_t data) {
      rtcm_setbitul(buff, pos, len, (uint64_t)data);
    }
    
    /* Get sign-magnitude bits, See Note 1, Table 3.3-1, RTCM 3.3
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * 
    eturn Bit field as a signed value.
     */
    int32_t rtcm_get_sign_magnitude_bit(const uint8_t *buff,
                                        uint32_t pos,
                                        uint8_t len) {
      int32_t value = rtcm_getbitu(buff, pos + 1, len - 1);
      return rtcm_getbitu(buff, pos, 1) ? -value : value;
    }
    
    /* Set sign-magnitude bits, See Note 1, Table 3.3-1, RTCM 3.3
     * param buff
     * param pos Position in buffer of start of bit field in bits.
     * param len Length of bit field in bits.
     * data data to encode
     */
    void rtcm_set_sign_magnitude_bit(uint8_t *buff,
                                     uint32_t pos,
                                     uint8_t len,
                                     int64_t data) {
      rtcm_setbitu(buff, pos, 1, (data < 0) ? 1 : 0);
      rtcm_setbitu(buff, pos + 1, len - 1, ((data < 0) ? -data : data));
    }

    bits.h

    /*
     * Copyright (C) 2018 Swift Navigation Inc.
     * Contact: Swift Navigation <dev@swiftnav.com>
     *
     * This source is subject to the license found in the file 'LICENSE' which must
     * be distributed together with this source. All other rights reserved.
     *
     * THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
     * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED
     * WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
     */
    
    #ifndef SWIFTNAV_RTCM3_BITS_H
    #define SWIFTNAV_RTCM3_BITS_H
    
    #ifdef __cplusplus
    extern "C" {
    #endif
    
    #include <stdint.h>
    
    uint32_t rtcm_getbitu(const uint8_t *buff, uint32_t pos, uint8_t len);
    uint64_t rtcm_getbitul(const uint8_t *buff, uint32_t pos, uint8_t len);
    int32_t rtcm_getbits(const uint8_t *buff, uint32_t pos, uint8_t len);
    int64_t rtcm_getbitsl(const uint8_t *buff, uint32_t pos, uint8_t len);
    void rtcm_setbitu(uint8_t *buff, uint32_t pos, uint32_t len, uint32_t data);
    void rtcm_setbitul(uint8_t *buff, uint32_t pos, uint32_t len, uint64_t data);
    void rtcm_setbits(uint8_t *buff, uint32_t pos, uint32_t len, int32_t data);
    void rtcm_setbitsl(uint8_t *buff, uint32_t pos, uint32_t len, int64_t data);
    int32_t rtcm_get_sign_magnitude_bit(const uint8_t *buff,
                                        uint32_t pos,
                                        uint8_t len);
    void rtcm_set_sign_magnitude_bit(uint8_t *buff,
                                        uint32_t pos,
                                        uint8_t len,
                                        int64_t data);
    #ifdef __cplusplus
    }
    #endif
    
    #endif /* SWIFTNAV_RTCM3_BITS_H */

     

    15. list

    redis-4.0.11srcadlist.h

    /* adlist.h - A generic doubly linked list implementation
     *
     * Copyright (c) 2006-2012, Salvatore Sanfilippo <antirez at gmail dot com>
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     *   * Redistributions of source code must retain the above copyright notice,
     *     this list of conditions and the following disclaimer.
     *   * Redistributions in binary form must reproduce the above copyright
     *     notice, this list of conditions and the following disclaimer in the
     *     documentation and/or other materials provided with the distribution.
     *   * Neither the name of Redis nor the names of its contributors may be used
     *     to endorse or promote products derived from this software without
     *     specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     */
    
    #ifndef __ADLIST_H__
    #define __ADLIST_H__
    
    /* Node, List, and Iterator are the only data structures used currently. */
    
    typedef struct listNode {
        struct listNode *prev;
        struct listNode *next;
        void *value;
    } listNode;
    
    typedef struct listIter {
        listNode *next;
        int direction;
    } listIter;
    
    typedef struct list {
        listNode *head;
        listNode *tail;
        void *(*dup)(void *ptr);
        void (*free)(void *ptr);
        int (*match)(void *ptr, void *key);
        unsigned long len;
    } list;
    
    /* Functions implemented as macros */
    #define listLength(l) ((l)->len)
    #define listFirst(l) ((l)->head)
    #define listLast(l) ((l)->tail)
    #define listPrevNode(n) ((n)->prev)
    #define listNextNode(n) ((n)->next)
    #define listNodeValue(n) ((n)->value)
    
    #define listSetDupMethod(l,m) ((l)->dup = (m))
    #define listSetFreeMethod(l,m) ((l)->free = (m))
    #define listSetMatchMethod(l,m) ((l)->match = (m))
    
    #define listGetDupMethod(l) ((l)->dup)
    #define listGetFree(l) ((l)->free)
    #define listGetMatchMethod(l) ((l)->match)
    
    /* Prototypes */
    list *listCreate(void);
    void listRelease(list *list);
    void listEmpty(list *list);
    list *listAddNodeHead(list *list, void *value);
    list *listAddNodeTail(list *list, void *value);
    list *listInsertNode(list *list, listNode *old_node, void *value, int after);
    void listDelNode(list *list, listNode *node);
    listIter *listGetIterator(list *list, int direction);
    listNode *listNext(listIter *iter);
    void listReleaseIterator(listIter *iter);
    list *listDup(list *orig);
    listNode *listSearchKey(list *list, void *key);
    listNode *listIndex(list *list, long index);
    void listRewind(list *list, listIter *li);
    void listRewindTail(list *list, listIter *li);
    void listRotate(list *list);
    void listJoin(list *l, list *o);
    
    /* Directions for iterators */
    #define AL_START_HEAD 0
    #define AL_START_TAIL 1
    
    #endif /* __ADLIST_H__ */

    redis-4.0.11srcadlist.c

    /* adlist.c - A generic doubly linked list implementation
     *
     * Copyright (c) 2006-2010, Salvatore Sanfilippo <antirez at gmail dot com>
     * All rights reserved.
     *
     * Redistribution and use in source and binary forms, with or without
     * modification, are permitted provided that the following conditions are met:
     *
     *   * Redistributions of source code must retain the above copyright notice,
     *     this list of conditions and the following disclaimer.
     *   * Redistributions in binary form must reproduce the above copyright
     *     notice, this list of conditions and the following disclaimer in the
     *     documentation and/or other materials provided with the distribution.
     *   * Neither the name of Redis nor the names of its contributors may be used
     *     to endorse or promote products derived from this software without
     *     specific prior written permission.
     *
     * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
     * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     * POSSIBILITY OF SUCH DAMAGE.
     */
    
    
    #include <stdlib.h>
    #include "adlist.h"
    
    /* Create a new list. The created list can be freed with
     * AlFreeList(), but private value of every node need to be freed
     * by the user before to call AlFreeList().
     *
     * On error, NULL is returned. Otherwise the pointer to the new list. */
    list *listCreate(void)
    {
        struct list *list;
    
        if ((list = malloc(sizeof(*list))) == NULL)
            return NULL;
        list->head = list->tail = NULL;
        list->len = 0;
        list->dup = NULL;
        list->free = NULL;
        list->match = NULL;
        return list;
    }
    
    /* Remove all the elements from the list without destroying the list itself. */
    void listEmpty(list *list)
    {
        unsigned long len;
        listNode *current, *next;
    
        current = list->head;
        len = list->len;
        while(len--) {
            next = current->next;
            if (list->free) list->free(current->value);
            free(current);
            current = next;
        }
        list->head = list->tail = NULL;
        list->len = 0;
    }
    
    /* Free the whole list.
     *
     * This function can't fail. */
    void listRelease(list *list)
    {
        listEmpty(list);
        free(list);
    }
    
    /* Add a new node to the list, to head, containing the specified 'value'
     * pointer as value.
     *
     * On error, NULL is returned and no operation is performed (i.e. the
     * list remains unaltered).
     * On success the 'list' pointer you pass to the function is returned. */
    list *listAddNodeHead(list *list, void *value)
    {
        listNode *node;
    
        if ((node = malloc(sizeof(*node))) == NULL)
            return NULL;
        node->value = value;
        if (list->len == 0) {
            list->head = list->tail = node;
            node->prev = node->next = NULL;
        } else {
            node->prev = NULL;
            node->next = list->head;
            list->head->prev = node;
            list->head = node;
        }
        list->len++;
        return list;
    }
    
    /* Add a new node to the list, to tail, containing the specified 'value'
     * pointer as value.
     *
     * On error, NULL is returned and no operation is performed (i.e. the
     * list remains unaltered).
     * On success the 'list' pointer you pass to the function is returned. */
    list *listAddNodeTail(list *list, void *value)
    {
        listNode *node;
    
        if ((node = malloc(sizeof(*node))) == NULL)
            return NULL;
        node->value = value;
        if (list->len == 0) {
            list->head = list->tail = node;
            node->prev = node->next = NULL;
        } else {
            node->prev = list->tail;
            node->next = NULL;
            list->tail->next = node;
            list->tail = node;
        }
        list->len++;
        return list;
    }
    
    list *listInsertNode(list *list, listNode *old_node, void *value, int after) {
        listNode *node;
    
        if ((node = malloc(sizeof(*node))) == NULL)
            return NULL;
        node->value = value;
        if (after) {
            node->prev = old_node;
            node->next = old_node->next;
            if (list->tail == old_node) {
                list->tail = node;
            }
        } else {
            node->next = old_node;
            node->prev = old_node->prev;
            if (list->head == old_node) {
                list->head = node;
            }
        }
        if (node->prev != NULL) {
            node->prev->next = node;
        }
        if (node->next != NULL) {
            node->next->prev = node;
        }
        list->len++;
        return list;
    }
    
    /* Remove the specified node from the specified list.
     * It's up to the caller to free the private value of the node.
     *
     * This function can't fail. */
    void listDelNode(list *list, listNode *node)
    {
        if (node->prev)
            node->prev->next = node->next;
        else
            list->head = node->next;
        if (node->next)
            node->next->prev = node->prev;
        else
            list->tail = node->prev;
        if (list->free) list->free(node->value);
        free(node);
        list->len--;
    }
    
    /* Returns a list iterator 'iter'. After the initialization every
     * call to listNext() will return the next element of the list.
     *
     * This function can't fail. */
    listIter *listGetIterator(list *list, int direction)
    {
        listIter *iter;
    
        if ((iter = malloc(sizeof(*iter))) == NULL) return NULL;
        if (direction == AL_START_HEAD)
            iter->next = list->head;
        else
            iter->next = list->tail;
        iter->direction = direction;
        return iter;
    }
    
    /* Release the iterator memory */
    void listReleaseIterator(listIter *iter) {
        free(iter);
    }
    
    /* Create an iterator in the list private iterator structure */
    void listRewind(list *list, listIter *li) {
        li->next = list->head;
        li->direction = AL_START_HEAD;
    }
    
    void listRewindTail(list *list, listIter *li) {
        li->next = list->tail;
        li->direction = AL_START_TAIL;
    }
    
    /* Return the next element of an iterator.
     * It's valid to remove the currently returned element using
     * listDelNode(), but not to remove other elements.
     *
     * The function returns a pointer to the next element of the list,
     * or NULL if there are no more elements, so the classical usage patter
     * is:
     *
     * iter = listGetIterator(list,<direction>);
     * while ((node = listNext(iter)) != NULL) {
     *     doSomethingWith(listNodeValue(node));
     * }
     *
     * */
    listNode *listNext(listIter *iter)
    {
        listNode *current = iter->next;
    
        if (current != NULL) {
            if (iter->direction == AL_START_HEAD)
                iter->next = current->next;
            else
                iter->next = current->prev;
        }
        return current;
    }
    
    /* Duplicate the whole list. On out of memory NULL is returned.
     * On success a copy of the original list is returned.
     *
     * The 'Dup' method set with listSetDupMethod() function is used
     * to copy the node value. Otherwise the same pointer value of
     * the original node is used as value of the copied node.
     *
     * The original list both on success or error is never modified. */
    list *listDup(list *orig)
    {
        list *copy;
        listIter iter;
        listNode *node;
    
        if ((copy = listCreate()) == NULL)
            return NULL;
        copy->dup = orig->dup;
        copy->free = orig->free;
        copy->match = orig->match;
        listRewind(orig, &iter);
        while((node = listNext(&iter)) != NULL) {
            void *value;
    
            if (copy->dup) {
                value = copy->dup(node->value);
                if (value == NULL) {
                    listRelease(copy);
                    return NULL;
                }
            } else
                value = node->value;
            if (listAddNodeTail(copy, value) == NULL) {
                listRelease(copy);
                return NULL;
            }
        }
        return copy;
    }
    
    /* Search the list for a node matching a given key.
     * The match is performed using the 'match' method
     * set with listSetMatchMethod(). If no 'match' method
     * is set, the 'value' pointer of every node is directly
     * compared with the 'key' pointer.
     *
     * On success the first matching node pointer is returned
     * (search starts from head). If no matching node exists
     * NULL is returned. */
    listNode *listSearchKey(list *list, void *key)
    {
        listIter iter;
        listNode *node;
    
        listRewind(list, &iter);
        while((node = listNext(&iter)) != NULL) {
            if (list->match) {
                if (list->match(node->value, key)) {
                    return node;
                }
            } else {
                if (key == node->value) {
                    return node;
                }
            }
        }
        return NULL;
    }
    
    /* Return the element at the specified zero-based index
     * where 0 is the head, 1 is the element next to head
     * and so on. Negative integers are used in order to count
     * from the tail, -1 is the last element, -2 the penultimate
     * and so on. If the index is out of range NULL is returned. */
    listNode *listIndex(list *list, long index) {
        listNode *n;
    
        if (index < 0) {
            index = (-index)-1;
            n = list->tail;
            while(index-- && n) n = n->prev;
        } else {
            n = list->head;
            while(index-- && n) n = n->next;
        }
        return n;
    }
    
    /* Rotate the list removing the tail node and inserting it to the head. */
    void listRotate(list *list) {
        listNode *tail = list->tail;
    
        if (listLength(list) <= 1) return;
    
        /* Detach current tail */
        list->tail = tail->prev;
        list->tail->next = NULL;
        /* Move it as head */
        list->head->prev = tail;
        tail->prev = NULL;
        tail->next = list->head;
        list->head = tail;
    }
    
    /* Add all the elements of the list 'o' at the end of the
     * list 'l'. The list 'other' remains empty but otherwise valid. */
    void listJoin(list *l, list *o) {
        if (o->head)
            o->head->prev = l->tail;
    
        if (l->tail)
            l->tail->next = o->head;
        else
            l->head = o->head;
    
        if (o->tail) l->tail = o->tail;
        l->len += o->len;
    
        /* Setup other as an empty list. */
        o->head = o->tail = NULL;
        o->len = 0;
    }

    14. array

    pjproject-2.10pjlibincludepjarray.h

    /* $Id$ */
    /* 
     * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
     * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
     *
     * This program 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 2 of the License, or
     * (at your option) any later version.
     *
     * This program 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, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     */
    #ifndef __PJ_ARRAY_H__
    #define __PJ_ARRAY_H__
    
    /**
     * @file array.h
     * @brief PJLIB Array helper.
     */
    #include <pj/types.h>
    
    PJ_BEGIN_DECL
    
    /**
     * @defgroup PJ_ARRAY Array helper.
     * @ingroup PJ_DS
     * @{
     *
     * This module provides helper to manipulate array of elements of any size.
     * It provides most used array operations such as insert, erase, and search.
     */
    
    /**
     * Insert value to the array at the given position, and rearrange the
     * remaining nodes after the position.
     *
     * @param array        the array.
     * @param elem_size the size of the individual element.
     * @param count        the CURRENT number of elements in the array.
     * @param pos        the position where the new element is put.
     * @param value        the value to copy to the new element.
     */
    PJ_DECL(void) pj_array_insert( void *array,
                       unsigned elem_size,
                       unsigned count,
                       unsigned pos,
                       const void *value);
    
    /**
     * Erase a value from the array at given position, and rearrange the remaining
     * elements post the erased element.
     *
     * @param array        the array.
     * @param elem_size the size of the individual element.
     * @param count        the current number of elements in the array.
     * @param pos        the index/position to delete.
     */
    PJ_DECL(void) pj_array_erase( void *array,
                      unsigned elem_size,
                      unsigned count,
                      unsigned pos);
    
    /**
     * Search the first value in the array according to matching function.
     *
     * @param array        the array.
     * @param elem_size the individual size of the element.
     * @param count        the number of elements.
     * @param matching  the matching function, which MUST return PJ_SUCCESS if 
     *            the specified element match.
     * @param result    the pointer to the value found.
     *
     * @return        PJ_SUCCESS if value is found, otherwise the error code.
     */
    PJ_DECL(pj_status_t) pj_array_find(   const void *array, 
                          unsigned elem_size, 
                          unsigned count, 
                          pj_status_t (*matching)(const void *value),
                          void **result);
    
    /**
     * @}
     */
    
    PJ_END_DECL
    
    
    #endif    /* __PJ_ARRAY_H__ */

    pjproject-2.10pjlibsrcpjarray.c

    /* $Id$ */
    /* 
     * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
     * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
     *
     * This program 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 2 of the License, or
     * (at your option) any later version.
     *
     * This program 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, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     */
    #include <pj/array.h>
    #include <pj/string.h>
    #include <pj/assert.h>
    #include <pj/errno.h>
    
    PJ_DEF(void) pj_array_insert( void *array,
                      unsigned elem_size,
                      unsigned count,
                      unsigned pos,
                      const void *value)
    {
        if (count && pos < count) {
        pj_memmove( (char*)array + (pos+1)*elem_size,
                (char*)array + pos*elem_size,
                (count-pos)*elem_size);
        }
        pj_memmove((char*)array + pos*elem_size, value, elem_size);
    }
    
    PJ_DEF(void) pj_array_erase( void *array,
                     unsigned elem_size,
                     unsigned count,
                     unsigned pos)
    {
        pj_assert(count != 0);
        if (pos < count-1) {
        pj_memmove( (char*)array + pos*elem_size,
                (char*)array + (pos+1)*elem_size,
                (count-pos-1)*elem_size);
        }
    }
    
    PJ_DEF(pj_status_t) pj_array_find( const void *array, 
                       unsigned elem_size, 
                       unsigned count, 
                       pj_status_t (*matching)(const void *value),
                       void **result)
    {
        unsigned i;
        const char *char_array = (const char*)array;
        for (i=0; i<count; ++i) {
        if ( (*matching)(char_array) == PJ_SUCCESS) {
            if (result) {
            *result = (void*)char_array;
            }
            return PJ_SUCCESS;
        }
        char_array += elem_size;
        }
        return PJ_ENOTFOUND;
    }

    13. memery pool

    12. base64

    pjproject-2.10pjlib-utilincludepjlib-utilase64.h

    /* $Id$ */
    /* 
     * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
     * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
     *
     * This program 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 2 of the License, or
     * (at your option) any later version.
     *
     * This program 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, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     */
    #ifndef __PJLIB_UTIL_BASE64_H__
    #define __PJLIB_UTIL_BASE64_H__
    
    /**
     * @file base64.h
     * @brief Base64 encoding and decoding
     */
    
    #include <pjlib-util/types.h>
    
    PJ_BEGIN_DECL
    
    /**
     * @defgroup PJLIB_UTIL_BASE64 Base64 Encoding/Decoding
     * @ingroup PJLIB_UTIL_ENCRYPTION
     * @{
     * This module implements base64 encoding and decoding.
     */
    
    /**
     * Helper macro to calculate the approximate length required for base256 to
     * base64 conversion.
     */
    #define PJ_BASE256_TO_BASE64_LEN(len)    (len * 4 / 3 + 3)
    
    /**
     * Helper macro to calculate the approximage length required for base64 to
     * base256 conversion.
     */
    #define PJ_BASE64_TO_BASE256_LEN(len)    (len * 3 / 4)
    
    
    /**
     * Encode a buffer into base64 encoding.
     *
     * @param input        The input buffer.
     * @param in_len    Size of the input buffer.
     * @param output    Output buffer. Caller must allocate this buffer with
     *            the appropriate size.
     * @param out_len   On entry, it specifies the length of the output buffer. 
     *            Upon return, this will be filled with the actual
     *            length of the output buffer.
     *
     * @return        PJ_SUCCESS on success.
     */
    PJ_DECL(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,
                         char *output, int *out_len);
    
    
    /**
     * Decode base64 string.
     *
     * @param input        Input string.
     * @param out        Buffer to store the output. Caller must allocate
     *            this buffer with the appropriate size.
     * @param out_len   On entry, it specifies the length of the output buffer. 
     *            Upon return, this will be filled with the actual
     *            length of the output.
     */
    PJ_DECL(pj_status_t) pj_base64_decode(const pj_str_t *input, 
                          pj_uint8_t *out, int *out_len);
    
    
    
    /**
     * @}
     */
    
    PJ_END_DECL
    
    
    #endif    /* __PJLIB_UTIL_BASE64_H__ */

    pjproject-2.10pjlib-utilsrcpjlib-utilase64.c

    /* $Id$ */
    /* 
     * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
     * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
     *
     * This program 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 2 of the License, or
     * (at your option) any later version.
     *
     * This program 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, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     */
    #include <pjlib-util/base64.h>
    #include <pj/assert.h>
    #include <pj/errno.h>
    
    #define INV        -1
    #define PADDING        '='
    
    static const char base64_char[] = {
        'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
        'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
        'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
        'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
        'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
        'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
        '8', '9', '+', '/' 
    };
    
    static int base256_char(char c)
    {
        if (c >= 'A' && c <= 'Z')
        return (c - 'A');
        else if (c >= 'a' && c <= 'z')
        return (c - 'a' + 26);
        else if (c >= '0' && c <= '9')
        return (c - '0' + 52);
        else if (c == '+')
        return (62);
        else if (c == '/')
        return (63);
        else {
        /* It *may* happen on bad input, so this is not a good idea.
         * pj_assert(!"Should not happen as '=' should have been filtered");
         */
        return INV;
        }
    }
    
    
    static void base256to64(pj_uint8_t c1, pj_uint8_t c2, pj_uint8_t c3, 
                int padding, char *output)
    {
        *output++ = base64_char[c1>>2];
        *output++ = base64_char[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
        switch (padding) {
        case 0:
        *output++ = base64_char[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
        *output = base64_char[c3 & 0x3F];
        break;
        case 1:
        *output++ = base64_char[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
        *output = PADDING;
        break;
        case 2:
        default:
        *output++ = PADDING;
        *output = PADDING;
        break;
        }
    }
    
    
    PJ_DEF(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,
                         char *output, int *out_len)
    {
        const pj_uint8_t *pi = input;
        pj_uint8_t c1, c2, c3;
        int i = 0;
        char *po = output;
    
        PJ_ASSERT_RETURN(input && output && out_len, PJ_EINVAL);
        PJ_ASSERT_RETURN(*out_len >= PJ_BASE256_TO_BASE64_LEN(in_len), 
                 PJ_ETOOSMALL);
    
        while (i < in_len) {
        c1 = *pi++;
        ++i;
    
        if (i == in_len) {
            base256to64(c1, 0, 0, 2, po);
            po += 4;
            break;
        } else {
            c2 = *pi++;
            ++i;
    
            if (i == in_len) {
            base256to64(c1, c2, 0, 1, po);
            po += 4;
            break;
            } else {
            c3 = *pi++;
            ++i;
            base256to64(c1, c2, c3, 0, po);
            }
        }
    
        po += 4;
        }
    
        *out_len = (int)(po - output);
        return PJ_SUCCESS;
    }
    
    
    PJ_DEF(pj_status_t) pj_base64_decode(const pj_str_t *input, 
                         pj_uint8_t *out, int *out_len)
    {
        const char *buf;
        int len;
        int i, j, k;
        int c[4];
    
        PJ_ASSERT_RETURN(input && out && out_len, PJ_EINVAL);
    
        buf = input->ptr;
        len = (int)input->slen;
        while (len && buf[len-1] == '=')
        --len;
    
        PJ_ASSERT_RETURN(*out_len >= PJ_BASE64_TO_BASE256_LEN(len), 
                 PJ_ETOOSMALL);
    
        for (i=0, j=0; i<len; ) {
        /* Fill up c, silently ignoring invalid characters */
        for (k=0; k<4 && i<len; ++k) {
            do {
            c[k] = base256_char(buf[i++]);
            } while (c[k]==INV && i<len);
        }
    
        if (k<4) {
            if (k > 1) {
            out[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4));
            if (k > 2) {
                out[j++] = (pj_uint8_t)
                       (((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2));
            }
            }
            break;
        }
    
        out[j++] = (pj_uint8_t)((c[0]<<2) | ((c[1] & 0x30)>>4));
        out[j++] = (pj_uint8_t)(((c[1] & 0x0F)<<4) | ((c[2] & 0x3C)>>2));
        out[j++] = (pj_uint8_t)(((c[2] & 0x03)<<6) | (c[3] & 0x3F));
        }
    
        pj_assert(j <= *out_len);
        *out_len = j;
    
        return PJ_SUCCESS;
    }

    11. color_table[]

    ffmpeg-4.1/libavutil/parseutils.c

    typedef struct {
        const char *name;            ///< a string representing the name of the color
        uint8_t     rgb_color[3];    ///< RGB values for the color
    } ColorEntry;
    
    static const ColorEntry color_table[] = {
        { "AliceBlue",            { 0xF0, 0xF8, 0xFF } },
        { "AntiqueWhite",         { 0xFA, 0xEB, 0xD7 } },
        { "Aqua",                 { 0x00, 0xFF, 0xFF } },
        { "Aquamarine",           { 0x7F, 0xFF, 0xD4 } },
        { "Azure",                { 0xF0, 0xFF, 0xFF } },
        { "Beige",                { 0xF5, 0xF5, 0xDC } },
        { "Bisque",               { 0xFF, 0xE4, 0xC4 } },
        { "Black",                { 0x00, 0x00, 0x00 } },
        { "BlanchedAlmond",       { 0xFF, 0xEB, 0xCD } },
        { "Blue",                 { 0x00, 0x00, 0xFF } },
        { "BlueViolet",           { 0x8A, 0x2B, 0xE2 } },
        { "Brown",                { 0xA5, 0x2A, 0x2A } },
        { "BurlyWood",            { 0xDE, 0xB8, 0x87 } },
        { "CadetBlue",            { 0x5F, 0x9E, 0xA0 } },
        { "Chartreuse",           { 0x7F, 0xFF, 0x00 } },
        { "Chocolate",            { 0xD2, 0x69, 0x1E } },
        { "Coral",                { 0xFF, 0x7F, 0x50 } },
        { "CornflowerBlue",       { 0x64, 0x95, 0xED } },
        { "Cornsilk",             { 0xFF, 0xF8, 0xDC } },
        { "Crimson",              { 0xDC, 0x14, 0x3C } },
        { "Cyan",                 { 0x00, 0xFF, 0xFF } },
        { "DarkBlue",             { 0x00, 0x00, 0x8B } },
        { "DarkCyan",             { 0x00, 0x8B, 0x8B } },
        { "DarkGoldenRod",        { 0xB8, 0x86, 0x0B } },
        { "DarkGray",             { 0xA9, 0xA9, 0xA9 } },
        { "DarkGreen",            { 0x00, 0x64, 0x00 } },
        { "DarkKhaki",            { 0xBD, 0xB7, 0x6B } },
        { "DarkMagenta",          { 0x8B, 0x00, 0x8B } },
        { "DarkOliveGreen",       { 0x55, 0x6B, 0x2F } },
        { "Darkorange",           { 0xFF, 0x8C, 0x00 } },
        { "DarkOrchid",           { 0x99, 0x32, 0xCC } },
        { "DarkRed",              { 0x8B, 0x00, 0x00 } },
        { "DarkSalmon",           { 0xE9, 0x96, 0x7A } },
        { "DarkSeaGreen",         { 0x8F, 0xBC, 0x8F } },
        { "DarkSlateBlue",        { 0x48, 0x3D, 0x8B } },
        { "DarkSlateGray",        { 0x2F, 0x4F, 0x4F } },
        { "DarkTurquoise",        { 0x00, 0xCE, 0xD1 } },
        { "DarkViolet",           { 0x94, 0x00, 0xD3 } },
        { "DeepPink",             { 0xFF, 0x14, 0x93 } },
        { "DeepSkyBlue",          { 0x00, 0xBF, 0xFF } },
        { "DimGray",              { 0x69, 0x69, 0x69 } },
        { "DodgerBlue",           { 0x1E, 0x90, 0xFF } },
        { "FireBrick",            { 0xB2, 0x22, 0x22 } },
        { "FloralWhite",          { 0xFF, 0xFA, 0xF0 } },
        { "ForestGreen",          { 0x22, 0x8B, 0x22 } },
        { "Fuchsia",              { 0xFF, 0x00, 0xFF } },
        { "Gainsboro",            { 0xDC, 0xDC, 0xDC } },
        { "GhostWhite",           { 0xF8, 0xF8, 0xFF } },
        { "Gold",                 { 0xFF, 0xD7, 0x00 } },
        { "GoldenRod",            { 0xDA, 0xA5, 0x20 } },
        { "Gray",                 { 0x80, 0x80, 0x80 } },
        { "Green",                { 0x00, 0x80, 0x00 } },
        { "GreenYellow",          { 0xAD, 0xFF, 0x2F } },
        { "HoneyDew",             { 0xF0, 0xFF, 0xF0 } },
        { "HotPink",              { 0xFF, 0x69, 0xB4 } },
        { "IndianRed",            { 0xCD, 0x5C, 0x5C } },
        { "Indigo",               { 0x4B, 0x00, 0x82 } },
        { "Ivory",                { 0xFF, 0xFF, 0xF0 } },
        { "Khaki",                { 0xF0, 0xE6, 0x8C } },
        { "Lavender",             { 0xE6, 0xE6, 0xFA } },
        { "LavenderBlush",        { 0xFF, 0xF0, 0xF5 } },
        { "LawnGreen",            { 0x7C, 0xFC, 0x00 } },
        { "LemonChiffon",         { 0xFF, 0xFA, 0xCD } },
        { "LightBlue",            { 0xAD, 0xD8, 0xE6 } },
        { "LightCoral",           { 0xF0, 0x80, 0x80 } },
        { "LightCyan",            { 0xE0, 0xFF, 0xFF } },
        { "LightGoldenRodYellow", { 0xFA, 0xFA, 0xD2 } },
        { "LightGreen",           { 0x90, 0xEE, 0x90 } },
        { "LightGrey",            { 0xD3, 0xD3, 0xD3 } },
        { "LightPink",            { 0xFF, 0xB6, 0xC1 } },
        { "LightSalmon",          { 0xFF, 0xA0, 0x7A } },
        { "LightSeaGreen",        { 0x20, 0xB2, 0xAA } },
        { "LightSkyBlue",         { 0x87, 0xCE, 0xFA } },
        { "LightSlateGray",       { 0x77, 0x88, 0x99 } },
        { "LightSteelBlue",       { 0xB0, 0xC4, 0xDE } },
        { "LightYellow",          { 0xFF, 0xFF, 0xE0 } },
        { "Lime",                 { 0x00, 0xFF, 0x00 } },
        { "LimeGreen",            { 0x32, 0xCD, 0x32 } },
        { "Linen",                { 0xFA, 0xF0, 0xE6 } },
        { "Magenta",              { 0xFF, 0x00, 0xFF } },
        { "Maroon",               { 0x80, 0x00, 0x00 } },
        { "MediumAquaMarine",     { 0x66, 0xCD, 0xAA } },
        { "MediumBlue",           { 0x00, 0x00, 0xCD } },
        { "MediumOrchid",         { 0xBA, 0x55, 0xD3 } },
        { "MediumPurple",         { 0x93, 0x70, 0xD8 } },
        { "MediumSeaGreen",       { 0x3C, 0xB3, 0x71 } },
        { "MediumSlateBlue",      { 0x7B, 0x68, 0xEE } },
        { "MediumSpringGreen",    { 0x00, 0xFA, 0x9A } },
        { "MediumTurquoise",      { 0x48, 0xD1, 0xCC } },
        { "MediumVioletRed",      { 0xC7, 0x15, 0x85 } },
        { "MidnightBlue",         { 0x19, 0x19, 0x70 } },
        { "MintCream",            { 0xF5, 0xFF, 0xFA } },
        { "MistyRose",            { 0xFF, 0xE4, 0xE1 } },
        { "Moccasin",             { 0xFF, 0xE4, 0xB5 } },
        { "NavajoWhite",          { 0xFF, 0xDE, 0xAD } },
        { "Navy",                 { 0x00, 0x00, 0x80 } },
        { "OldLace",              { 0xFD, 0xF5, 0xE6 } },
        { "Olive",                { 0x80, 0x80, 0x00 } },
        { "OliveDrab",            { 0x6B, 0x8E, 0x23 } },
        { "Orange",               { 0xFF, 0xA5, 0x00 } },
        { "OrangeRed",            { 0xFF, 0x45, 0x00 } },
        { "Orchid",               { 0xDA, 0x70, 0xD6 } },
        { "PaleGoldenRod",        { 0xEE, 0xE8, 0xAA } },
        { "PaleGreen",            { 0x98, 0xFB, 0x98 } },
        { "PaleTurquoise",        { 0xAF, 0xEE, 0xEE } },
        { "PaleVioletRed",        { 0xD8, 0x70, 0x93 } },
        { "PapayaWhip",           { 0xFF, 0xEF, 0xD5 } },
        { "PeachPuff",            { 0xFF, 0xDA, 0xB9 } },
        { "Peru",                 { 0xCD, 0x85, 0x3F } },
        { "Pink",                 { 0xFF, 0xC0, 0xCB } },
        { "Plum",                 { 0xDD, 0xA0, 0xDD } },
        { "PowderBlue",           { 0xB0, 0xE0, 0xE6 } },
        { "Purple",               { 0x80, 0x00, 0x80 } },
        { "Red",                  { 0xFF, 0x00, 0x00 } },
        { "RosyBrown",            { 0xBC, 0x8F, 0x8F } },
        { "RoyalBlue",            { 0x41, 0x69, 0xE1 } },
        { "SaddleBrown",          { 0x8B, 0x45, 0x13 } },
        { "Salmon",               { 0xFA, 0x80, 0x72 } },
        { "SandyBrown",           { 0xF4, 0xA4, 0x60 } },
        { "SeaGreen",             { 0x2E, 0x8B, 0x57 } },
        { "SeaShell",             { 0xFF, 0xF5, 0xEE } },
        { "Sienna",               { 0xA0, 0x52, 0x2D } },
        { "Silver",               { 0xC0, 0xC0, 0xC0 } },
        { "SkyBlue",              { 0x87, 0xCE, 0xEB } },
        { "SlateBlue",            { 0x6A, 0x5A, 0xCD } },
        { "SlateGray",            { 0x70, 0x80, 0x90 } },
        { "Snow",                 { 0xFF, 0xFA, 0xFA } },
        { "SpringGreen",          { 0x00, 0xFF, 0x7F } },
        { "SteelBlue",            { 0x46, 0x82, 0xB4 } },
        { "Tan",                  { 0xD2, 0xB4, 0x8C } },
        { "Teal",                 { 0x00, 0x80, 0x80 } },
        { "Thistle",              { 0xD8, 0xBF, 0xD8 } },
        { "Tomato",               { 0xFF, 0x63, 0x47 } },
        { "Turquoise",            { 0x40, 0xE0, 0xD0 } },
        { "Violet",               { 0xEE, 0x82, 0xEE } },
        { "Wheat",                { 0xF5, 0xDE, 0xB3 } },
        { "White",                { 0xFF, 0xFF, 0xFF } },
        { "WhiteSmoke",           { 0xF5, 0xF5, 0xF5 } },
        { "Yellow",               { 0xFF, 0xFF, 0x00 } },
        { "YellowGreen",          { 0x9A, 0xCD, 0x32 } },
    };

    10. hardware operations wraper

    /**
     * Sound stream operations.
     */
    typedef struct pjmedia_aud_stream_op
    {
        /**
         * See #pjmedia_aud_stream_get_param()
         */
        pj_status_t (*get_param)(pjmedia_aud_stream *strm,
                     pjmedia_aud_param *param);
    
        /**
         * See #pjmedia_aud_stream_get_cap()
         */
        pj_status_t (*get_cap)(pjmedia_aud_stream *strm,
                   pjmedia_aud_dev_cap cap,
                   void *value);
    
        /**
         * See #pjmedia_aud_stream_set_cap()
         */
        pj_status_t (*set_cap)(pjmedia_aud_stream *strm,
                   pjmedia_aud_dev_cap cap,
                   const void *value);
    
        /**
         * See #pjmedia_aud_stream_start()
         */
        pj_status_t (*start)(pjmedia_aud_stream *strm);
    
        /**
         * See #pjmedia_aud_stream_stop().
         */
        pj_status_t (*stop)(pjmedia_aud_stream *strm);
    
        /**
         * See #pjmedia_aud_stream_destroy().
         */
        pj_status_t (*destroy)(pjmedia_aud_stream *strm);
    
    } pjmedia_aud_stream_op;
    
    static pjmedia_aud_stream_op alsa_stream_op =
    {
        &alsa_stream_get_param,
        &alsa_stream_get_cap,
        &alsa_stream_set_cap,
        &alsa_stream_start,
        &alsa_stream_stop,
        &alsa_stream_destroy
    };

    9. PJSIP-SIMPLE's own error codes/messages

    pjproject-2.10pjlib-utilsrcpjlib-utilerrno.c

    /* $Id$ */
    /* 
     * Copyright (C) 2008-2011 Teluu Inc. (http://www.teluu.com)
     * Copyright (C) 2003-2008 Benny Prijono <benny@prijono.org>
     *
     * This program 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 2 of the License, or
     * (at your option) any later version.
     *
     * This program 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, write to the Free Software
     * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
     */
    #include <pjlib-util/errno.h>
    #include <pjlib-util/types.h>
    #include <pj/assert.h>
    #include <pj/string.h>
    
    
    
    /* PJLIB_UTIL's own error codes/messages 
     * MUST KEEP THIS ARRAY SORTED!!
     * Message must be limited to 64 chars!
     */
    #if defined(PJ_HAS_ERROR_STRING) && PJ_HAS_ERROR_STRING!=0
    static const struct 
    {
        int code;
        const char *msg;
    } err_str[] = 
    {
        /* STUN errors */
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNRESOLVE,    "Unable to resolve STUN server" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINMSGTYPE,    "Unknown STUN message type" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINMSGLEN,    "Invalid STUN message length" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINATTRLEN,    "STUN attribute length error" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINATTRTYPE,    "Invalid STUN attribute type" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNININDEX,    "Invalid STUN server/socket index" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOBINDRES,    "No STUN binding response in the message" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNRECVERRATTR,    "Received STUN error attribute" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOMAP,    "No STUN mapped address attribute" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOTRESPOND,    "Received no response from STUN server" ),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNSYMMETRIC,    "Symetric NAT detected by STUN" ),
    
        /* XML errors */
        PJ_BUILD_ERR( PJLIB_UTIL_EINXML,        "Invalid XML message" ),
    
        /* JSON errors */
        PJ_BUILD_ERR( PJLIB_UTIL_EINJSON,        "Invalid JSON document" ),
    
        /* DNS errors */
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSQRYTOOSMALL,    "DNS query packet buffer is too small"),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSINSIZE,    "Invalid DNS packet length"),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSINCLASS,    "Invalid DNS class"),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNAMEPTR,    "Invalid DNS name pointer"),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSINNSADDR,    "Invalid DNS nameserver address"),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSNONS,        "No nameserver is in DNS resolver"),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSNOWORKINGNS,    "No working DNS nameserver"),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSNOANSWERREC,    "No answer record in the DNS response"),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNSINANSWER,    "Invalid DNS answer"),
    
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_FORMERR,    "DNS "Format error""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_SERVFAIL,    "DNS "Server failure""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NXDOMAIN,    "DNS "Name Error""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTIMPL,    "DNS "Not Implemented""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_REFUSED,    "DNS "Refused""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_YXDOMAIN,    "DNS "The name exists""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_YXRRSET,    "DNS "The RRset (name, type) exists""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NXRRSET,    "DNS "The RRset (name, type) does not exist""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTAUTH,    "DNS "Not authorized""),
        PJ_BUILD_ERR( PJLIB_UTIL_EDNS_NOTZONE,    "DNS "The zone specified is not a zone""),
    
        /* STUN */
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNTOOMANYATTR,    "Too many STUN attributes"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNUNKNOWNATTR,    "Unknown STUN attribute"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINADDRLEN,    "Invalid STUN socket address length"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNIPV6NOTSUPP,    "STUN IPv6 attribute not supported"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOTRESPONSE,    "Expecting STUN response message"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNINVALIDID,    "STUN transaction ID mismatch"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOHANDLER,    "Unable to find STUN handler for the request"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNMSGINTPOS,    "Found non-FINGERPRINT attr. after MESSAGE-INTEGRITY"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNFINGERPOS,    "Found STUN attribute after FINGERPRINT"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOUSERNAME,    "Missing STUN USERNAME attribute"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNMSGINT,    "Missing/invalid STUN MESSAGE-INTEGRITY attribute"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNDUPATTR,    "Found duplicate STUN attribute"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNOREALM,    "Missing STUN REALM attribute"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNNONCE,    "Missing/stale STUN NONCE attribute value"),
        PJ_BUILD_ERR( PJLIB_UTIL_ESTUNTSXFAILED,    "STUN transaction terminates with failure"),
    
        /* HTTP Client */
        PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINURL,    "Invalid URL format"),
        PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINPORT,    "Invalid URL port number"),
        PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINCHDR,    "Incomplete response header received"),
        PJ_BUILD_ERR( PJLIB_UTIL_EHTTPINSBUF,    "Insufficient buffer"),
        PJ_BUILD_ERR( PJLIB_UTIL_EHTTPLOST,            "Connection lost"),
    
        /* CLI */
        PJ_BUILD_ERR( PJ_CLI_EEXIT,                    "Exit current session"),
        PJ_BUILD_ERR( PJ_CLI_EMISSINGARG,            "Missing argument"),
        PJ_BUILD_ERR( PJ_CLI_ETOOMANYARGS,            "Too many arguments"),
        PJ_BUILD_ERR( PJ_CLI_EINVARG,            "Invalid argument"),
        PJ_BUILD_ERR( PJ_CLI_EBADNAME,            "Command name already exists"),
        PJ_BUILD_ERR( PJ_CLI_EBADID,            "Command id already exists"),
        PJ_BUILD_ERR( PJ_CLI_EBADXML,            "Invalid XML format"),
        PJ_BUILD_ERR( PJ_CLI_ETELNETLOST,            "Connection lost"),
    };
    #endif    /* PJ_HAS_ERROR_STRING */
    
    
    /*
     * pjlib_util_strerror()
     */
    pj_str_t pjlib_util_strerror(pj_status_t statcode, 
                     char *buf, pj_size_t bufsize )
    {
        pj_str_t errstr;
    
    #if defined(PJ_HAS_ERROR_STRING) && (PJ_HAS_ERROR_STRING != 0)
    
        if (statcode >= PJLIB_UTIL_ERRNO_START && 
        statcode < PJLIB_UTIL_ERRNO_START + PJ_ERRNO_SPACE_SIZE)
        {
        /* Find the error in the table.
         * Use binary search!
         */
        int first = 0;
        int n = PJ_ARRAY_SIZE(err_str);
    
        while (n > 0) {
            int half = n/2;
            int mid = first + half;
    
            if (err_str[mid].code < statcode) {
            first = mid+1;
            n -= (half+1);
            } else if (err_str[mid].code > statcode) {
            n = half;
            } else {
            first = mid;
            break;
            }
        }
    
    
        if (PJ_ARRAY_SIZE(err_str) && err_str[first].code == statcode) {
            pj_str_t msg;
            
            msg.ptr = (char*)err_str[first].msg;
            msg.slen = pj_ansi_strlen(err_str[first].msg);
    
            errstr.ptr = buf;
            pj_strncpy_with_null(&errstr, &msg, bufsize);
            return errstr;
    
        } 
        }
    
    #endif    /* PJ_HAS_ERROR_STRING */
    
    
        /* Error not found. */
        errstr.ptr = buf;
        errstr.slen = pj_ansi_snprintf(buf, bufsize, 
                       "Unknown pjlib-util error %d",
                       statcode);
        if (errstr.slen < 1 || errstr.slen >= (pj_ssize_t)bufsize)
        errstr.slen = bufsize - 1;
        return errstr;
    }
    
    
    PJ_DEF(pj_status_t) pjlib_util_init(void)
    {
        pj_status_t status;
        
        status = pj_register_strerror(PJLIB_UTIL_ERRNO_START, 
                      PJ_ERRNO_SPACE_SIZE, 
                      &pjlib_util_strerror);
        pj_assert(status == PJ_SUCCESS);
    
        return status;
    }

    8. define our own boolean type

    /* define our own boolean type */
    typedef int pj_bool_t;
    #define true ((pj_bool_t)1)
    #define false ((pj_bool_t)0)

    7. getopt_long(bluez/Sdptool.c)

    static struct {
        char *cmd;
        int (*func)(int argc, char **argv);
        char *doc;
    } command[] = {
        { "search",  cmd_search,      "Search for a service"          },
        { "browse",  cmd_browse,      "Browse all available services" },
        { "records", cmd_records,     "Request all records"           },
        { "add",     cmd_add,         "Add local service"             },
        { "del",     cmd_del,         "Delete local service"          },
        { "get",     cmd_get,         "Get local service"             },
        { "setattr", cmd_setattr,     "Set/Add attribute to a SDP record"          },
        { "setseq",  cmd_setseq,      "Set/Add attribute sequence to a SDP record" },
        { 0, 0, 0 }
    };
    
    static void usage(void)
    {
        int i, pos = 0;
    
        printf("sdptool - SDP tool v%s
    ", VERSION);
        printf("Usage:
    "
            "	sdptool [options] <command> [command parameters]
    ");
        printf("Options:
    "
            "	-h		Display help
    "
            "	-i		Specify source interface
    ");
    
        printf("Commands:
    ");
        for (i = 0; command[i].cmd; i++)
            printf("	%-4s		%s
    ", command[i].cmd, command[i].doc);
    
        printf("
    Services:
    	");
        for (i = 0; service[i].name; i++) {
            printf("%s ", service[i].name);
            pos += strlen(service[i].name) + 1;
            if (pos > 60) {
                printf("
    	");
                pos = 0;
            }
        }
        printf("
    ");
    }
    
    static struct option main_options[] = {
        { "help",    0, 0, 'h' },
        { "device",    1, 0, 'i' },
        { 0, 0, 0, 0 }
    };
    
    int main(int argc, char *argv[])
    {
        int i, opt;
    
        bacpy(&interface, BDADDR_ANY);
    
        while ((opt=getopt_long(argc, argv, "+i:h", main_options, NULL)) != -1) {
            switch(opt) {
            case 'i':
                if (!strncmp(optarg, "hci", 3))
                    hci_devba(atoi(optarg + 3), &interface);
                else
                    str2ba(optarg, &interface);
                break;
    
            case 'h':
                usage();
                exit(0);
    
            default:
                exit(1);
            }
        }
    
        argc -= optind;
        argv += optind;
        optind = 0;
    
        if (argc < 1) {
            usage();
            exit(1);
        }
    
        for (i = 0; command[i].cmd; i++)
            if (strncmp(command[i].cmd, argv[0], 4) == 0)
                return command[i].func(argc, argv);
    
        return 1;
    }

    6. fgets + stdin (human-computer interaction)

    static pj_bool_t simple_input(const char *title, char *buf, pj_size_t len)
    {
        char *p;
    
        printf("%s (empty to cancel): ", title); fflush(stdout);
        if (fgets(buf, (int)len, stdin) == NULL)
        return PJ_FALSE;
    
        /* Remove trailing newlines. */
        for (p=buf; ; ++p) {
        if (*p=='
    ' || *p=='
    ') *p='';
        else if (!*p) break;
        }
    
        if (!*buf)
        return PJ_FALSE;
    
        return PJ_TRUE;
    }

    example:

    static void ui_answer_call()
    {
        pjsua_call_info call_info;
        char buf[128];
        pjsua_msg_data msg_data_;
    
        if (current_call != -1) {
        pjsua_call_get_info(current_call, &call_info);
        } else {
        /* Make compiler happy */
        call_info.role = PJSIP_ROLE_UAC;
        call_info.state = PJSIP_INV_STATE_DISCONNECTED;
        }
    
        if (current_call == -1 ||
        call_info.role != PJSIP_ROLE_UAS ||
        call_info.state >= PJSIP_INV_STATE_CONNECTING)
        {
        puts("No pending incoming call");
        fflush(stdout);
        return;
    
        } else {
        int st_code;
        char contact[120];
        pj_str_t hname = { "Contact", 7 };
        pj_str_t hvalue;
        pjsip_generic_string_hdr hcontact;
    
        if (!simple_input("Answer with code (100-699)", buf, sizeof(buf)))
            return;
    
        st_code = my_atoi(buf);
        if (st_code < 100)
            return;
    
        pjsua_msg_data_init(&msg_data_);
    
        if (st_code/100 == 3) {
            if (!simple_input("Enter URL to be put in Contact",
            contact, sizeof(contact)))
            return;
            hvalue = pj_str(contact);
            pjsip_generic_string_hdr_init2(&hcontact, &hname, &hvalue);
    
            pj_list_push_back(&msg_data_.hdr_list, &hcontact);
        }
    
        /*
        * Must check again!
        * Call may have been disconnected while we're waiting for
        * keyboard input.
        */
        if (current_call == -1) {
            puts("Call has been disconnected");
            fflush(stdout);
            return;
        }
    
        pjsua_call_answer2(current_call, &call_opt, st_code, NULL, &msg_data_);
        }
    }
    5. 指针的应用
    1)用指针来改变变量/指针的值
    #include <stdio.h>
    #include <stdlib.h>
    
    int main()
    {
        int i = 9;
        int* p = &i;
    
        *p = 0xb;
        //用指针改变一个变量的值
        printf("i=0x%x
    ",i);
        printf("p=0x%x
    ",p);
    
        int** q = &p;
    
        **q = 0xc;
    
        //用二级指针改变一个变量的值
        printf("i=0x%x
    ",i);
        printf("p=0x%x
    ",p);
    
        *q = (int *)0xFFFFFFFF;
        //用二级指针改变一个指针的值
        printf("i=0x%x
    ",i);
        printf("p=0x%x
    ",p);
    
        return 0;
    }

    2)用函数来改变指针的值

    # include <stdio.h>
    void f(int ** q);
    int main(void)
    {
        int i = 9;
        int * p = &i;
        printf("p=0x%x
    ", p);
        f(&p);
        printf("p=0x%x
    ", p);
    
        return 0;
    }
    void f(int ** q)
    {
        *q = (int *)0xFFFFFFFF;
    }

    4. union与数据的拆分与合并以及大小端的判断

    1) 将int型的i拆分成4字节char型的c

    #include<stdio.h>  
    union var{  
            char c[4];  
            int i;  
    };  
      
    int main(){  
            union var data;  
            data.i = 0x11020304; 
            printf("%x
    ",data.c[0]);
    printf("%x ",data.c[1]);
    printf("%x ",data.c[2]);
         printf("%x ",data.c[3]);
         return 0;
    }

    2) 合并就是反过来

    #include<stdio.h>  
    union var{  
            char c[4];  
            int i;  
    };  
      
    int main(){  
            union var data;  
            data.c[0] = 0x04;
            data.c[1] = 0x03;
            data.c[2] = 0x02;  
            data.c[3] = 0x11;  
            printf("%x
    ",data.i); 
         return 0; }

    3) 大小端的判断

    #include<stdio.h>  
    union var{  
            char c[4];  
            int i;  
    };  
      
    int main(){  
            union var data;  
            data.i = 0x11020304; 
            printf("%x
    ",data.c[0]);
            printf("%x
    ",data.c[1]);
            printf("%x
    ",data.c[2]);
         printf("%x
    ",data.c[3]);
    
            if( data.c[0] == 0x11 )
            {
              printf("Systerm is BigEndian");
            }
         return 0; 
    }

    3. 连接符#的应用

    1) 连接数值类型用双#

    #include <stdio.h>
    
    #define   COMB(a,b,c)   a##b##c
      
    void main()
    {    
           printf("%d
    ",COMB(1,2,3));  
    }

    2) 连接字符类型用单#

    #include <stdio.h>
    
    #define   CATSTR(n)   "abcd"#n  
    
    void main()  
    {  
            printf("%s
    ",CATSTR(100));  
    }

    2. 函数指针散转

    //预存的APP响应
    void (*CmdCallbackArray[APP_CMD_MAX])(uint8_t *para) = {
        0 ,
        FirewareManageCallback , // FirewareManage = 1
        DataSyncCallback ,
        SetCmdCallback,
        HintCmdCallback,
        0,
        BindCallback,
        FactoryTestCallback,
        LogCtrlCallback
    
    };
    
    bool  App_Data_L1_DataParse( uint8_t *L1_Packet,uint8_t *L1_Payload){
      bool ret=true;
    
      uint8_t para[60] = {0};
      uint16_t L2_len = 0;
      uint16_t check_sum = 0;
      L2_len =((((uint16_t)L1_Packet[5])<<8)|((uint16_t)L1_Packet[6]));
    
      check_sum = CRC_calc(&L1_Packet[9] , &L1_Packet[9+L2_len]);
    
      if( ( (((uint16_t)L1_Packet[7])<<8)|((uint16_t)L1_Packet[8]) ) ==  check_sum )
      {
        //正常接收,进入L2_Command_Content
        para[0] = L1_Packet[2];
        memcpy(&para[1],&L1_Packet[10],L2_len-1);
        CmdCallbackArray[L1_Packet[9]](para);
      }
      return ret;
    }

    1. 函数指针收敛

    typedef struct task
    {
        pthread_t id;
        int fd;
        uint8_t buf[1024];
        int size;
    }task_t;
    
    void (*task_array[])(int fd, uint8_t* buf, uint8_t size) = {
        qx_raw ,
        qx_raw_2_ubx ,
        qx_raw_2_ubx_zhd ,
        zhd_raw,
        zhd_raw_2_ubx,
        zhd_raw_2_ubx_zhd,
    };
    
    static void* 
    task_done(void *arg)
    {
        task_t task = *(task_t*)(arg);
        int i = 0;
        while(task_array[i] != NULL){
            (task_array[i])(task.fd, task.buf, task.size); 
            i++;
        }
        printf ("task %d done !
    ", task.fd);     
    }
  • 相关阅读:
    .net 面试题 没事多看看。。。。
    分享一下我记忆23种设计模式的方法 <转。。>
    再次写给我们这些浮躁的程序员 《搜集的。。。》
    C#验证邮箱,电话,手机,数字,英文,日期,身份证,邮编,网址,IP类.. (转后整理)
    javascript和jquery使用技巧集
    jQuery 增加 删除 修改select option .
    设计模式(二)
    JavaScript string 字符串类型的扩展方法
    26个jQuery使用技巧
    jBPM开发入门指南(1)
  • 原文地址:https://www.cnblogs.com/dong1/p/13796692.html
Copyright © 2011-2022 走看看