static size_t wsgi_getheaders(Request* request, PyObject* buf) { char* bufp = PyString_AS_STRING(buf); Py_ssize_t i; #define buf_write(src, len) \ do { \ size_t n = len; \ const char* s = src; \ while(n--) *bufp++ = *s++; \ } while(0) #define buf_write2(src) buf_write(src, strlen(src)) buf_write2("HTTP/1.1 "); buf_write(PyString_AS_STRING(request->status), PyString_GET_SIZE(request->status)); for(i=0; i<PyList_GET_SIZE(request->headers); ++i) { PyObject *tuple = PyList_GET_ITEM(request->headers, i); PyObject *field = PyTuple_GET_ITEM(tuple, 0), *value = PyTuple_GET_ITEM(tuple, 1); buf_write2("\r\n"); buf_write(PyString_AS_STRING(field), PyString_GET_SIZE(field)); buf_write2(": "); buf_write(PyString_AS_STRING(value), PyString_GET_SIZE(value)); } if(request->state.chunked_response) buf_write2("\r\nTransfer-Encoding: chunked"); buf_write2("\r\n\r\n"); return bufp - PyString_AS_STRING(buf); }
static int CreateCellAddressTable(FILE *h, const struct vobgroup *va) /* outputs a VMGM_C_ADT, VTSM_C_ADT or VTS_C_ADT structure containing pointers to all cells. */ { int i, p, k; buf_init(); p = 8; for (k = 0; k < va->numvobs; k++) { const struct vob * const thisvob = va->vobs[k]; for (i = 0; i < thisvob->numvobus; i++) { if (!i || thisvob->vobu[i].vobcellid != thisvob->vobu[i - 1].vobcellid) { /* starting a new cell */ if (i) { buf_write4(p + 8, thisvob->vobu[i - 1].lastsector); /* ending sector within VOB in previous entry */ p += 12; } /*if*/ buf_write2(p, thisvob->vobu[i].vobcellid >> 8); /* VOBidn */ buf_write1(p + 2, thisvob->vobu[i].vobcellid); /* CELLidn */ buf_write4(p + 4, thisvob->vobu[i].sector); /* starting sector within VOB */ } /*if*/ } /*for*/ buf_write4(p + 8, thisvob->vobu[i - 1].lastsector); /* ending sector within VOB in last entry */ p += 12; } /*for*/ buf_write4(4, p - 1); /* end address (last byte of last entry) */ // first 2 bytes of C_ADT contains number of vobs buf_write2(0, va->numvobs); p = (p + 2047) & (-2048); /* round up to whole sectors */ nfwrite(bigbuf, p, h); return p / 2048; /* nr sectors written */ } /*CreateCellAddressTable*/
static int Create_TT_SRPT ( FILE *h, const struct toc_summary *ts, int vtsstart /* starting sector for VTS */ ) /* creates a TT_SRPT structure containing pointers to all the titles on the disc. */ { int i, j, k, p, tn; buf_init(); j = vtsstart; tn = 0; p = 8; /* offset to first entry */ for (i = 0; i < ts->numvts; i++) { for (k = 0; k < ts->vts[i].numtitles; k++) { buf_write1(0 + p, 0x3c); /* title type = one sequential PGC, jump/link/call may be found in all places, PTT & time play/search uops not inhibited */ buf_write1(1 + p, 0x1); /* number of angles always 1 for now */ buf_write2(2 + p, ts->vts[i].numchapters[k]); /* number of chapters (PTTs) */ buf_write1(6 + p, i + 1); /* video titleset number, VTSN */ buf_write1(7 + p, k + 1); /* title nr within VTS, VTS_TTN */ buf_write4(8 + p, j); // start sector for VTS tn++; p += 12; /* offset to next entry */ } /*for*/ j += ts->vts[i].numsectors; } /*for*/ buf_write2(0, tn); // # of titles buf_write4(4, p - 1); /* end address (last byte of last entry) */ p = (p + 2047) & (-2048); /* round up to next whole sector */ nfwrite(bigbuf, p, h); return p / 2048; /* nr sectors generated */ } /*Create_TT_SRPT*/
static size_t wsgi_getheaders(Request* request, PyObject* buf) { char* bufp = PyString_AS_STRING(buf); #define buf_write(src, len) \ do { \ size_t n = len; \ const char* s = src; \ while(n--) *bufp++ = *s++; \ } while(0) #define buf_write2(src) buf_write(src, strlen(src)) /* First line, e.g. "HTTP/1.1 200 Ok" */ buf_write2("HTTP/1.1 "); buf_write(PyString_AS_STRING(request->status), PyString_GET_SIZE(request->status)); /* Headers, from the `request->headers` mapping. * [("Header1", "value1"), ("Header2", "value2")] * --> "Header1: value1\r\nHeader2: value2" */ for(Py_ssize_t i=0; i<PyList_GET_SIZE(request->headers); ++i) { PyObject *tuple = PyList_GET_ITEM(request->headers, i); PyObject *field = PyTuple_GET_ITEM(tuple, 0), *value = PyTuple_GET_ITEM(tuple, 1); buf_write2("\r\n"); buf_write(PyString_AS_STRING(field), PyString_GET_SIZE(field)); buf_write2(": "); buf_write(PyString_AS_STRING(value), PyString_GET_SIZE(value)); } /* See `wsgi_call_application` */ if(request->state.keep_alive) { buf_write2("\r\nConnection: Keep-Alive"); if(request->state.chunked_response) { buf_write2("\r\nTransfer-Encoding: chunked"); } } else { buf_write2("\r\nConnection: close"); } buf_write2("\r\n\r\n"); return bufp - PyString_AS_STRING(buf); }
static int Create_PTT_SRPT(FILE *h, const struct pgcgroup *t) /* creates the VTS_PTT_SRPT and VTS_PTT tables for each title. */ { int i, j, p; buf_init(); buf_write2(0, t->numpgcs); // # of titles p = 8 + t->numpgcs * 4; /* start generating VTS_PTT entries here */ assert(p <= 2048); // need to make sure all the pgc pointers fit in the first sector because of // dvdauthor.c:ScanIfo for (j = 0; j < t->numpgcs; j++) { const struct pgc * const pgc = t->pgcs[j]; int pgm = 1, k; buf_write4(8 + j * 4, p); /* offset to VTS_PTT for title */ for (i = 0; i < pgc->numsources; i++) /* generate the associated VTS_PTT entries */ for (k = 0; k < pgc->sources[i]->numcells; k++) { const struct cell * const thiscell = &pgc->sources[i]->cells[k]; if (thiscell->scellid != thiscell->ecellid) switch (thiscell->ischapter) { case CELL_CHAPTER_PROGRAM: buf_write1(1 + p, j + 1); /* PGCN low byte */ buf_write1(3 + p, pgm); /* PGN low byte */ p += 4; /* fallthru */ case CELL_PROGRAM: pgm++; /* keep right count for next chapter */ break; case CELL_NEITHER: /* fine */ break; } /*switch*/ } /*for; for*/ } /*for*/ buf_write4(4, p - 1); /* end address (last byte of last VTS_PTT) */ p = (p + 2047) & (-2048); /* round up to next whole sector */ nfwrite(bigbuf, p, h); /* write it all out */ return p / 2048; /* nr sectors generated */ } /*Create_PTT_SRPT*/
static size_t wsgi_getheaders(Request* request, PyObject* buf) { char* bufp = PyString_AS_STRING(buf); int have_http11 = (request->parser.parser.http_major > 0 && request->parser.parser.http_minor > 0); #define buf_write(src, len) \ do { \ size_t n = len; \ const char* s = src; \ while(n--) *bufp++ = *s++; \ } while(0) #define buf_write2(src) buf_write(src, strlen(src)) buf_write2("HTTP/1.1 "); buf_write(PyString_AS_STRING(request->status), PyString_GET_SIZE(request->status)); for(Py_ssize_t i=0; i<PyList_GET_SIZE(request->headers); ++i) { PyObject *tuple = PyList_GET_ITEM(request->headers, i); PyObject *field = PyTuple_GET_ITEM(tuple, 0), *value = PyTuple_GET_ITEM(tuple, 1); buf_write2("\r\n"); buf_write(PyString_AS_STRING(field), PyString_GET_SIZE(field)); buf_write2(": "); buf_write(PyString_AS_STRING(value), PyString_GET_SIZE(value)); } if(!have_http11) { if(request->state.chunked_response) /* Can't do chunked with HTTP 1.0 */ buf_write2("\r\nConnection: close"); else if (request->state.keep_alive) /* Need to be explicit with HTTP 1.0 */ buf_write2("\r\nConnection: Keep-Alive"); } else if(request->state.chunked_response) buf_write2("\r\nTransfer-Encoding: chunked"); buf_write2("\r\n\r\n"); return bufp - PyString_AS_STRING(buf); }