• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2013 The Chromium Authors. All rights reserved.
2  * Use of this source code is governed by a BSD-style license that can be
3  * found in the LICENSE file. */
4 
5 
6 /* XRay string pool */
7 
8 /* String pool holds a large pile of strings. */
9 /* It is up to higher level data structures to avoid duplicates. */
10 /* It is up to higher level data structures to provide fast lookups. */
11 
12 /* _GNU_SOURCE must be defined prior to the inclusion of string.h
13  * so that strnlen is available with glibc */
14 #define _GNU_SOURCE
15 #include <stdlib.h>
16 #include <string.h>
17 #include "xray/xray_priv.h"
18 
19 #if defined(XRAY)
20 
21 struct XRayStringPoolNode {
22   struct XRayStringPoolNode* next;
23   char strings[XRAY_STRING_POOL_NODE_SIZE];
24 };
25 
26 
27 struct XRayStringPool {
28   struct XRayStringPoolNode* head;
29   struct XRayStringPoolNode* current;
30   int index;
31 };
32 
33 
XRayStringPoolAllocNode()34 static struct XRayStringPoolNode* XRayStringPoolAllocNode() {
35   struct XRayStringPoolNode* s;
36   s = (struct XRayStringPoolNode *)XRayMalloc(sizeof(*s));
37   s->next = NULL;
38   return s;
39 }
40 
41 
XRayStringPoolCurrentNodeSpaceAvail(struct XRayStringPool * pool)42 static int XRayStringPoolCurrentNodeSpaceAvail(struct XRayStringPool* pool) {
43   int i = pool->index;
44   return (XRAY_STRING_POOL_NODE_SIZE - i) - 1;
45 }
46 
47 
48 /* Append a string to the string pool. */
XRayStringPoolAppend(struct XRayStringPool * pool,const char * src)49 char* XRayStringPoolAppend(struct XRayStringPool* pool, const char* src) {
50   /* Add +1 to STRING_POOL_NODE_SIZE to detect large strings */
51   /* Add +1 to strnlen result to account for string termination */
52   int n = strnlen(src, XRAY_STRING_POOL_NODE_SIZE + 1) + 1;
53   int a = XRayStringPoolCurrentNodeSpaceAvail(pool);
54   char* dst;
55   /* Don't accept strings larger than the pool node. */
56   if (n >= (XRAY_STRING_POOL_NODE_SIZE - 1))
57     return NULL;
58   /* If string doesn't fit, alloc a new node. */
59   if (n > a) {
60     pool->current->next = XRayStringPoolAllocNode();
61     pool->current = pool->current->next;
62     pool->index = 0;
63   }
64   /* Copy string and return a pointer to copy. */
65   dst = &pool->current->strings[pool->index];
66   strcpy(dst, src);
67   pool->index += n;
68   return dst;
69 }
70 
71 
72 /* Create & initialize a string pool instance. */
XRayStringPoolCreate()73 struct XRayStringPool* XRayStringPoolCreate() {
74   struct XRayStringPool* pool;
75   pool = (struct XRayStringPool*)XRayMalloc(sizeof(*pool));
76   pool->head = XRayStringPoolAllocNode();
77   pool->current = pool->head;
78   return pool;
79 }
80 
81 
82 /* Free a string pool. */
XRayStringPoolFree(struct XRayStringPool * pool)83 void XRayStringPoolFree(struct XRayStringPool* pool) {
84   struct XRayStringPoolNode* n = pool->head;
85   while (NULL != n) {
86     struct XRayStringPoolNode* c = n;
87     n = n->next;
88     XRayFree(c);
89   }
90   XRayFree(pool);
91 }
92 
93 #endif  /* XRAY */
94 
95