Exemple #1
0
static int lxs_tablib_joinall(lua_State* const L)
{
    lxs_assert_stack_begin(L);
    size_t      dlen;
    const char* delim = luaL_checklstring(L, 1, &dlen);

    int top = lua_gettop(L);
    if (top <= 2)
        luaL_argerror(L, 2, "need at least 2 arguments");
    else if (lua_isnoneornil(L, 2))
        luaL_argerror(L, 2, "cannot be nil");

    xbuf_decl(b);
    xbuf_init(L, b);
    for (int i = 2; i <= top; ++i)
    {
        size_t      elen;
        const char* estr = luaL_checklstring(L, i, &elen);

        if (elen > 0)
            xbuf_addlstring(L, b, estr, elen);

        if (dlen > 0 && i + 1 <= top)
            xbuf_addlstring(L, b, delim, dlen);
    }
    xbuf_pushresult(L, b);

#if LUAXS_STR_PERSISTENT_BUFFER
    lxs_assert_stack_end(L, 1);
#else
    lxs_assert_stack_end(L, 1 + (b.lvl - 1));
#endif
    return 1;
}
Exemple #2
0
static void
pipeline_lua_init(const char *name)
{
    indigo_core_message_listener_register(message_listener);
    xbuf_init(&upload_chunks);
    pipeline_lua_stats_init();

    ind_ovs_pktin_socket_register(&pktin_soc, process_pktin, PKTIN_INTERVAL,
                                  PKTIN_BURST_SIZE);

    reset_lua();
}
Exemple #3
0
WRAP_API int
wrap_mvwinsnstr(WINDOW *win, int y, int x, uchar2 *str, int n)
{
#if defined(CURSES_WIDE) && SIZEOF_WCHAR_T == 2
	return mvwins_nwstr(win, y, x, str, n);
#elif defined(CURSES_WIDE)
	wchar_t stackbuf[BUFFER_SIZE];
	xbuffer xinput, xoutput;
	int ret;

	xbuf_init_uc(&xinput, str, n, XBUF_FILL);
	xbuf_init_wc(&xoutput, stackbuf, BUFFER_SIZE, XBUF_EXPANDABLE);

	ret = unicode_to_wchar(&xinput, &xoutput);
	if (ret < 0)
		goto do_exit;
	ret = xbuf_tzero_wc(&xoutput);
	if (ret < 0)
		goto do_exit;
	ret = mvwins_nwstr(win, y, x, xbuf_data_wc(&xoutput), xbuf_len_wc(&xoutput));
do_exit:
	xbuf_free(&xoutput);
	return ret;
#else
	char stackbuf[BUFFER_SIZE];
	xbuffer xinput, xoutput;
	int ret;

	xbuf_init_uc(&xinput, str, n, XBUF_FILL);
	xbuf_init(&xoutput, stackbuf, BUFFER_SIZE, XBUF_EXPANDABLE);

	ret = unicode_to_char(&xinput, &xoutput);
	if (ret < 0)
		goto do_exit;
	ret = xbuf_tzero(&xoutput);
	if (ret < 0)
		goto do_exit;
	ret = mvwinsnstr(win, y, x, xbuf_data(&xoutput), xbuf_len(&xoutput));
do_exit:
	xbuf_free(&xoutput);
	return ret;
#endif
}
Exemple #4
0
int main(int argc, char *argv[])
{
  xbuf_t data;
  xbuf_init(&data);
  xbuf_cat(&data,
    "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi sit amet "
    "quam purus, vitae fermentum turpis. Nam in augue mi. Donec suscipit moles"
    "tie felis, eget rhoncus risus pharetra in. Sed id diam id felis fringilla"
    " adipiscing non vitae odio. Etiam vulputate tristique elit, nec eleifend"
    " mauris scelerisque eu. Vestibulum luctus, enim a luctus posuere, mauris"
    " mauris rutrum mi, eget fermentum massa tortor id enim. Nulla feugiat "
    "porta urna quis laoreet. Morbi metus ante, commodo quis dictum vitae, "
    "rhoncus a libero. Cras viverra feugiat orci id interdum. Duis pulvinar "
    "neque id erat adipiscing facilisis. Maecenas vitae urna risus, euismod"
    " sollicitudin risus."
  );
  
  char gzipped[4096];
  
  u32 len = zlib_cmp(data.ptr, 0, data.len, gzipped, sizeof(gzipped), 1);
  
  printf("Original length: %i\n", data.len);
  printf("Gzipped length:  %i\n\n", len);
  
  xbuf_t *reply = get_reply(argv);
  
  xbuf_xcat(reply,
    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/plain\r\n"
    "Content-Length: %i\r\n"
    "Content-Encoding: gzip\r\n\r\n",
    len
  );
  
  xbuf_ncat(reply, gzipped, len);
  
  xbuf_free(&data);

  return -1; //custom headers
}
Exemple #5
0
/// table.join(table[, delimiter])
///
/// Concatenables all entries of a *table*, optionally separating them using a
/// *delimiter* string.
/// The table is traversed using *next* and which means traversal order is
/// undefined or the non-vector part of the table.
///
/// Usage example:
///     table.join({ ''            }, ',') --> ''
///     table.join({ '', ''        }, ',') --> ','
///     table.join({ 'a', 'b'      }, ',') --> 'a,b'
static int libE_join(lua_State* const L)
{
    lxs_assert_stack_begin(L);

    luaL_checktype(L, 1, LUA_TTABLE);

    size_t      dlen;
    const char* delim = luaL_optlstring(L, 2, NULL, &dlen);

    xbuf_decl(b);
    xbuf_init(L, b);

    bool add_delim = false;

    lua_pushnil(L);
    while (lua_next(L, 1))
    {
        if (add_delim)
            xbuf_addlstring(L, b, delim, dlen);
        else if (dlen > 0)
            add_delim = true;

        size_t      elen;
        const char* estr = luaL_checklstring(L, -1, &elen);

        if (elen > 0)
            xbuf_addlstring(L, b, estr, elen);

        lua_pop(L, 1);
    }
    xbuf_pushresult(L, b);

#if LUAXS_STR_PERSISTENT_BUFFER
    lxs_assert_stack_end(L, 1);
#else
    lxs_assert_stack_end(L, 1 + (b.lvl - 1));
#endif
    return 1;
}
Exemple #6
0
int list_threads(kv_item *item, xbuf_t *reply)
{
  Thread *thread = (Thread*)item->val;
  
  xbuf_t thread_li;
  xbuf_init(&thread_li);
  
  //using sprintf-like formatting
  xbuf_xcat(&thread_li, 
    "<li>"
    "<a href='/?forum_simple/act=t/id=%llu'>%s</a> (%lu)"
    "</li>",
    thread->id, thread->title.ptr, thread->posts.nbr_items
  );
  
  char *pos = (char*)xbuf_findstr(reply, "<!--tpl-->");
  if (pos) xbuf_insert(reply, pos, thread_li.len, thread_li.ptr);

  xbuf_free(&thread_li);

  return 1;
}
Exemple #7
0
/// table.joini(table[, delimiter])
///
/// Concatenables all entries of a *table*, optionally separating them using a
/// *delimiter* string.
/// Only the vector part of a table is traversed.
///
/// Usage example:
///     table.joini({ ''            }, ',') --> ''
///     table.joini({ '', ''        }, ',') --> ','
///     table.joini({ 'a', 'b'      }, ',') --> 'a,b'
static int libE_joini(lua_State* const L)
{
    lxs_assert_stack_begin(L);

    luaL_checktype(L, 1, LUA_TTABLE);

    size_t      dlen;
    const char* delim = luaL_optlstring(L, 2, NULL, &dlen);

    xbuf_decl(b);
    xbuf_init(L, b);

    int vlen = lua_objlen(L, 1);
    for (int i = 1; i <= vlen; ++i)
    {
        lua_rawgeti(L, 1, i);
    
        size_t      elen;
        const char* estr = luaL_checklstring(L, -1, &elen);

        if (elen > 0)
            xbuf_addlstring(L, b, estr, elen);

        if (dlen > 0 && i + 1 <= vlen)
            xbuf_addlstring(L, b, delim, dlen);

        lua_pop(L, 1);
    }
    xbuf_pushresult(L, b);

#if LUAXS_STR_PERSISTENT_BUFFER
    lxs_assert_stack_end(L, 1);
#else
    lxs_assert_stack_end(L, 1 + (b.lvl - 1));
#endif
    return 1;
}
Exemple #8
0
int main(int argc, char *argv[])
{
  //initialize Key-Value store--------------------------------------------------
  kv_t **vhost_ptr = (kv_t**)get_env(argv, US_VHOST_DATA), //persistent ptr
       *forum_store = 0; //convenience pointer (var->m instead of (*var)->m)
  
  if (vhost_ptr && !*vhost_ptr)
  {
    *vhost_ptr = (kv_t*)malloc(sizeof(kv_t));
    
    //threads and posts stored here
    kv_init(*vhost_ptr, "forum_store", 1024, 0, 0, 0);
  } forum_store = *vhost_ptr;
  //----------------------------------------------------------------------------
  
  //setup GET and POST variables------------------------------------------------
  char *act = "", *id = "", *title = "", *body = "";
  get_arg("act=",   &act,   argc, argv); //action ('t' or 'p')
  get_arg("id=",    &id,    argc, argv); //id of thread
  get_arg("title=", &title, argc, argv); //title of thread
  get_arg("body=",  &body,  argc, argv); //body of post
  
  char *end = 0;
  u64 int_id = strtoll(id, &end, 10); //string to integer
  if (*end) int_id = 0; //require a numeric ID
  //----------------------------------------------------------------------------
  
  //response sent to browser is stored here-------------------------------------
  //templates are rendered into this buffer
  xbuf_t *reply = get_reply(argv);
  xbuf_cat(reply, base_tpl); //set base template
  //----------------------------------------------------------------------------
  
  //HTTP state of a connection
  http_t *http = (http_t*)get_env(argv, HTTP_HEADERS);
  
  redirect: //simulate HTTP, <meta>, or JavaScript redirect without page reload
  
  //choose what to do based on the value of 'act'-------------------------------
  switch (*act)
  {
    //regarding a post
    case 'p':
    {
      switch (http->h_method) //GET or POST
      {
        //new post--------------------------------------------------------------
        case HTTP_POST:
        {
          //get the thread to which this post belongs
          Thread *thread = (Thread*)kv_get(forum_store, (char*)&int_id, sizeof(int_id));
          
          if (!thread) //thread not found
          {
            xbuf_repl(reply, "<!--tpl-->", http_error(404));
            return 404;
          }
          
          //allocate memory
          Post *post = calloc(1, sizeof(*post));
          
          //initialize members
          xbuf_init(&post->body);
          
          //define members
          post->id = thread->posts.nbr_items + 1;
          xbuf_cat(&post->body, *body ? body : " ");
          
          //add post to thread
          kv_add(&thread->posts, &(kv_item) {
            .key = (char*)&post->id,
            .klen = sizeof(post->id),
            .val = (char*)post,
            .flags = 0,
          });
          
          //setup redirect
          http->h_method = HTTP_GET;
          *act = 't';
          
          goto redirect;
        } break;
        //----------------------------------------------------------------------
      }
    } break;
    
    //regarding a thread
    case 't':
    {
      switch (http->h_method)
      {
        //view a thread---------------------------------------------------------
        case HTTP_GET:
        {
          Thread *thread = (Thread*)kv_get(forum_store, (char*)&int_id, sizeof(int_id));
          
          if (!thread)
          {
            xbuf_repl(reply, "<!--tpl-->", http_error(404));
            return 404;
          }
          
          //replace template variables with dynamic values
          xbuf_repl(reply, "<!--form-->", post_form);
          xbuf_repl(reply, "<!--title-->", thread->title.ptr);
          xbuf_repl(reply, "<!--id-->", id);
          
          //for each post, render its template and insert it into reply
          kv_do(&thread->posts, 0, 0, (kv_proc_t)&list_posts, (void*)reply);
        } break;
        //----------------------------------------------------------------------
        
        //create a thread-------------------------------------------------------
        case HTTP_POST:
        {
          Thread *thread = calloc(1, sizeof(*thread));
          
          xbuf_init(&thread->title);
          kv_init(&thread->posts, "posts", 1024, 0, 0, 0);
          
          thread->id = forum_store->nbr_items + 1;
          xbuf_cat(&thread->title, *title ? title : " ");
          
          //add thread to KV store
          kv_add(forum_store, &(kv_item) {
            .key = (char*)&thread->id,
            .klen = sizeof(thread->id),
            .val = (char*)thread,
            .flags = 0,
          });
          
          http->h_method = HTTP_GET;
          *act = 0;
          
          goto redirect;
        } break;
        //----------------------------------------------------------------------
      }
    } break;
Exemple #9
0
// ----------------------------------------------------------------------------
// imported functions:
//   get_reply(): get a pointer on the 'reply' dynamic buffer from the server
//       getus(): get current time in microseconds (1 millisecond = 1,000 us)
//     get_env(): get connection's 'environment' variables from the server
//    xbuf_cat(): like strcat(), but it works in the specified dynamic buffer 
//   gif_build(): build an in-memory GIF image from a bitmap and palette
// ----------------------------------------------------------------------------
int main(int argc, char *argv[])
{
   // -------------------------------------------------------------------------
   // get a pointer on the server reply
   // -------------------------------------------------------------------------
   xbuf_t *reply = get_reply(argv);

   // -------------------------------------------------------------------------
   // allocate memory for a raw bitmap
   // -------------------------------------------------------------------------
   int   w = 800, h = 800, nbcolors = 256, wXh = w * h;
   u8 *bmp = (u8*)malloc(wXh);
   if(!bmp) return 503; // service unavailable

   // -------------------------------------------------------------------------
   // render the Mandelbrot set in our bitmap
   // -------------------------------------------------------------------------
   fractals(bmp, w, h, nbcolors);

   // -------------------------------------------------------------------------
   // display the palette (useful when playing with 'tabcol[]' values)
   // -------------------------------------------------------------------------
   {  
      #define ROUND(a) ((a) > 0 ? (int)((a)+0.5) : -(int)(0.5-(a)))
      u8 *p = bmp;
      int i = h, wd20 = w / 20;
      float color = 0, col = (float)nbcolors / (float)h;
      while(i--)
      {
         color += col;
         memset(p, ROUND(color) & 255, wd20);
         p += w;
      }   
   }

   // -------------------------------------------------------------------------
   // build a smooth multi-gradient color palette from the fixed values below
   // -------------------------------------------------------------------------
   static 
   rgb_t tabcol[]={ {  0,   0, 128}, // Med. Blue
                    {  0, 100, 200}, // Light Blue
                    {100, 160, 160}, // Cyan
                    {  0, 220, 100}, // Green
                    {255, 255,   0}, // Yellow
                    {255, 128,   0}, // Orange
                    {128,   0,   0}, // Med. Red
                    { 64,   0,   0}, // Dark Red
                    {128,   0,   0}, // Med. Red
                    {255, 128,   0}, // Orange
                    {255, 255,   0}, // Yellow
                    {  0, 220, 100}, // Green 
                    {100, 160, 160}, // Cyan
                    {  0, 100, 200}, // Light Blue
                    {  0,   0, 128}, // Med. Blue

                    { 64,   0,   0}, // Dark Red
                    {128,   0,   0}, // Med. Red
                    {255, 128,   0}, // Orange
                    {255, 255,   0}, // Yellow
                    {  0, 220, 100}, // Green 
                    {100, 160, 160}, // Cyan
                    {  0, 100, 200}, // Light Blue
                    {  0,   0, 128}, // Med.  Blue
                    {  0,   0,  64}, // Dark  Blue
                  }, *tab = tabcol;
                  
   // -------------------------------------------------------------------------
   // just for fun, select different colors for each call
   // -------------------------------------------------------------------------
   static u32 call = 0;
   u32 ncols = sizeof(tabcol) / sizeof(rgb_t);
   switch(call)
   {
      case 0: tab =  tabcol;     ncols = 10; break; // blue
      case 1: tab = &tabcol[ 4]; ncols = 10; break; // yellow
      case 2: tab = &tabcol[ 7]; ncols =  7; break; // dark red
      case 3: tab = &tabcol[ 1]; ncols = 16; break; // rainbow -
   }
   call = (call + 1) & 3;
   // generate the palette with our defined gradient steps
   u8 pal[768]; dr_gradient(pal, nbcolors, tab, ncols);
   // nice palete but we want a black body to delimit the mandelbrot set
   memset(pal + ((nbcolors - (nbcolors / 16)) * 3), 0, (nbcolors / 16) * 3);

   // -------------------------------------------------------------------------
   // create custom HTTP response headers to send a GIF file
   // -------------------------------------------------------------------------
   // (G-WAN automatically generates headers if none are provided but it can't
   //  guess all MIME types so this automatic feature is for 'text/html' only
   //  ...unless you explicitly specify the reply buffer MIME type)

#ifdef BUILD_CUSTOM_HEADERS // old way of doing things

   // get the current HTTP date (like "Wed, 02 Jun 2010 06:49:37 GMT")
   u8 *date = (u8*)get_env(argv, SERVER_DATE);

   xbuf_xcat(reply,
             "HTTP/1.1 200 OK\r\n"
             "Date: %s\r\n"
             "Last-Modified: %s\r\n"
             "Content-type: image/gif\r\n"
             "Content-Length:       \r\n" // make room for the for GIF length
             "Connection: close\r\n\r\n",
             date, date);

   // -------------------------------------------------------------------------
   // make sure that we have enough space in the 'reply' buffer
   // (we are going to fill it directly from gif_build(), not via xbuf_xxx)
   // -------------------------------------------------------------------------
   // (if we have not enough memory, we will get a 'graceful' crash)
   if(reply->allocated < (wXh / 10)) // very gross approximation
   {
      if(!xbuf_growto(reply, wXh / 10)) // resize reply
      {
         xbuf_init(reply);
         xbuf_ncat(reply, " ", 1);
         reply->len = 0; // discart pointless data, keep allocated memory
         return 503; // error: we could not allocate enough memory
      }
   }

   // -------------------------------------------------------------------------
   // save the place where to patch the void 'Content-Length' HTTP Header
   // -------------------------------------------------------------------------
   char *p = reply->ptr + reply->len
         - (sizeof("\r\nConnection: close\r\n\r\n") - 1);

   // -------------------------------------------------------------------------
   // append a GIF image (-1:no transparency, 0: no comment) to 'reply'
   // -------------------------------------------------------------------------
   int len = gif_build((u8*)(reply->ptr + reply->len), bmp, w, h, 
                       pal, nbcolors, 
                       -1, 0);
   if(len < 0) len = 0; // (len == -1) if gif_build() failed
   reply->len += len;  // add the GIF size to the 'reply' buffer length
   free(bmp);
   
   // -------------------------------------------------------------------------
   // store the GIF size in the empty space of the 'Content-Length' header
   // -------------------------------------------------------------------------
   u32toa(p, len);
   
#else // #ifdef BUILD_CUSTOM_HEADERS // works with any supported MIME type
   
   // -------------------------------------------------------------------------
   // specify a MIME type so we don't have to build custom HTTP headers
   // -------------------------------------------------------------------------
   char *mime = (char*)get_env(argv, REPLY_MIME_TYPE);
   // note that we setup the FILE EXTENTION, not the MIME type:
   mime[0] = '.'; mime[1] = 'g'; mime[2] = 'i'; mime[3] = 'f'; mime[4] = 0; 

   // -------------------------------------------------------------------------
   // make sure that we have enough space in the 'reply' buffer
   // (we are going to fill it directly from gif_build(), not via xbuf_xxx)
   // -------------------------------------------------------------------------
   // (if we have not enough memory, we will get a 'graceful' crash)
   if(reply->allocated < (wXh / 10)) // very gross approximation
   {
      if(!xbuf_growto(reply, wXh / 10)) // resize reply
      {
         xbuf_init(reply);
         xbuf_ncat(reply, " ", 1);
         reply->len = 0; // discart pointless data, keep allocated memory
         return 503; // error: we could not allocate enough memory
      }
   }

   // -------------------------------------------------------------------------
   // append a GIF image (-1:no transparency, 0: no comment) to 'reply'
   // -------------------------------------------------------------------------
   int len = gif_build((u8*)(reply->ptr + reply->len), bmp, w, h, 
                       pal, nbcolors, 
                       -1, 0);
   if(len < 0) len = 0; // (len == -1) if gif_build() failed
   reply->len += len;  // add the GIF size to the 'reply' buffer length
   free(bmp);
   
#endif // #else #ifdef BUILD_CUSTOM_HEADERS

   return 200; // return an HTTP code (200:'OK')
}