HTTP-XSHeaders

 view release on metacpan or  search on metacpan

util.c  view on Meta::CPAN

          PNode* node = &list->data[j];
          ++num;

          STRLEN len;
          char* str = SvPV( (SV*)node->ptr, len );
          GLOG(("=X= %s: returning %2d - str [%s]", func, num, str));
          if (rpos > 0) {
            rstr[rpos++] = ',';
            rstr[rpos++] = ' ';
          }

          memcpy(rstr + rpos, str, len);
          rpos += len;
        }

        rstr[rpos] = '\0';
        PUSHs(sv_2mortal(newSVpv(rstr, rpos)));
        GMEM_DEL(rstr, char*, size);
      }
    }

    PUTBACK;
  }

  if (want == G_ARRAY) {
    int num = 0;
    int j;
    GLOG(("=X= %s: returning as %d elements", func, count));
    EXTEND(SP, count);
    for (j = 0; j < list->ulen; ++j) {
      PNode* node = &list->data[j];
      ++num;

      PUSHs( (SV*)node->ptr );
    }

    PUTBACK;
  }
}

char* format_all(pTHX_ HList* h, int sort, const char* endl, int* size) {
  int le = strlen(endl);
  int j;
  *size = 64;

  if (sort) {
    hlist_sort(h);
  }

  for (j = 0; j < h->ulen; ++j) {
    HNode* hn = &h->data[j];
    const char* header = hn->header->name;
    int lh = strlen(header);
    PList* pl = hn->values;
    int k;
    for (k = 0; k < pl->ulen; ++k) {
      PNode* pn = &pl->data[k];
      const char* value = SvPV_nolen( (SV*) pn->ptr );
      int lv = strlen(value);
      /* string_cleanup always emits a trailing newl ("le" bytes) for
       * values that don't already end in "\n"; the original formula
       * did not account for that, producing a heap-buffer-overflow
       * when many empty (lv == 0) values were serialised. The +le
       * term below closes that gap. */
      *size += lh + 2 + lv + lv * le + le;
    }
  }

  {
    char* rstr;
    int rpos = 0;
    GMEM_NEW(rstr, char*, *size);
    for (j = 0; j < h->ulen; ++j) {
      HNode* hn = &h->data[j];
      const char* header = hn->header->name;
      int lh = strlen(header);
      PList* pl = hn->values;
      int k;
      PNode *pn;
      const char *value;
      for (k = 0; k < pl->ulen; ++k) {
        memcpy(rstr + rpos, header, lh);
        rpos += lh;
        rstr[rpos++] = ':';
        rstr[rpos++] = ' ';

        pn = &pl->data[k];
        value = SvPV_nolen( (SV*) pn->ptr );
        rpos += string_cleanup(value, rstr + rpos, *size - rpos, endl);
      }
    }

    rstr[rpos] = '\0';
    GLOG(("=X= format_all (%d/%d) [%s]", rpos, *size, rstr));
    return rstr;
  }
}

static int string_append(char* buf, int pos, int max, const char* str) {
  int k;
  for (k = 0; str[k] != '\0' && pos < max; ++k) {
    buf[pos++] = str[k];
  }
  return pos;
}

static int string_cleanup(const char* str, char* buf, int len, const char* newl) {
  int pos = 0;
  int last_nonblank = -1;
  int saw_newline = 0;
  int j;
  for (j = 0; str[j] != '\0'; ++j) {
    char c = str[j];
    int emit_cr = 0;
    if (c == '\r' && str[j + 1] == '\n') {
      if (strchr(newl, '\r') == NULL) {
        emit_cr = 1;
      }
      ++j;
      c = '\n';
    }



( run in 0.323 second using v1.01-cache-2.11-cpan-483215c6ad5 )