//create a JsonPair object while pair found sgdm::StackGuard<JsonValue>&& JsonParser::ParsePair(){ sgdm::StackGuard<JsonValue> pairName(new JsonName(idString)); getNextTok(); if(currentTok != ':'){ return Error("Expecting :"); } else{ getNextTok(); //eat : sgdm::StackGuard<JsonValue> pairValue(std::move(ParsePrimary())); return std::move(new JsonPair(std::move(pairName),std::move(pairValue))); } }
//create a JsonObject object while object found sgdm::StackGuard<JsonValue>&& JsonParser::ParseObject(){ if(currentTok != '{'){ return Error("Expecting { at entity beginning"); } else{ sgdm::StackGuard<JsonValue> resObject(new JsonObject()); getNextTok(); //eat { while(currentTok != '}'){ if(currentTok == ',') getNextTok(); //eat , resObject->push(std::move(ParsePair())); } getNextTok(); //eat } return std::move(resObject); } }
//create a JsonArray object while array found sgdm::StackGuard<JsonValue>&& JsonParser::ParseArray(){ if(currentTok != '['){ return Error("Expecting [ at the beginning"); } sgdm::StackGuard<JsonValue> array(new JsonArray()); getNextTok(); while(currentTok != ']'){ if (currentTok == ','){ getNextTok(); continue; } else{ array->push(std::move(ParsePrimary())); } } getNextTok(); //eat ] return std::move(array); }
//top level parse function sgdm::StackGuard<JsonValue>&& JsonParser::ParsePrimary(){ switch(currentTok){ case tok_endl: return std::move(Error("primary fail")); case tok_identifier: return std::move(ParseName()); case tok_integer: return std::move(ParseInteger()); case tok_double: return std::move(ParseDouble()); case '[': return std::move(ParseArray(alloc)); case '{': return std::move(ParseObject(alloc)); default: return std::move(Error("unknown token found near place" + std::to_string(indexCount))); } sgdm::StackGuard<JsonValue>&& JsonParser::Parse(){ getNextTok(); return std::move(ParsePrimary(alloc)); }
//create a JsonName object while string found sgdm::StackGuard<JsonValue>&& JsonParser::ParseName(){ sgdm::StackGuard<JsonValue> res(new JsonName(idString)); getNextTok(); return std::move(res); }
//create a JsonDouble object while double found sgdm::StackGuard<JsonValue>&& JsonParser::ParseDouble(){ sgdm::StackGuard<JsonValue> res(new JsonDouble(inputDouble)); getNextTok(); return std::move(res); }
/* Patch a file */ static int patch(char *path) { struct stat sbuf; FILE *ifp, *ofp, *dsiFp; char dsiName[MAX_FNAME], dsiPath[MAX_FNAME]; char tmpFile[MAX_FNAME], saveFile[MAX_FNAME]; char searchPat[MAX_FNAME], truePat[MAX_FNAME], falsePat[MAX_FNAME]; char *dsiBuf, *cp, *ep, *start, *end, *tok, *tag, *ext, *inBuf; char *startDsi, *ip; ssize len, rc; int c, i, level, line, patched; dsiBuf = 0; patched = 0; ifp = ofp = dsiFp = 0; if (*path == '.' && path[1] == '/') { path += 2; } if (*path == '/') { fprintf(stderr, "dsi: Path must be relative: %s\n", path); return -1; } for (level = 0, cp = path; *cp; cp++) { if (*cp == '/') { level++; } } if (verbose) { printf("Patching %s\n", path); } cp = parentDir; for (i = 0; i < level; i++) { *cp++ = '.'; *cp++ = '.'; *cp++ = '/'; } *cp = '\0'; ifp = fopen(path, "r" MPR_TEXT); if (ifp == 0) { fprintf(stderr, "dsi: Can't open %s\n", path); return -1; } stat(path, &sbuf); inBuf = (char*) malloc((int) sbuf.st_size + 1); rc = fread(inBuf, 1, (int) sbuf.st_size, ifp); if (rc < 0) { fprintf(stderr, "dsi: Can't read file %s\n", path); free(inBuf); return -1; } inBuf[rc] = '\0'; sprintf(tmpFile, "%s.new", path); ofp = fopen(tmpFile, "w" MPR_TEXT); if (ofp == 0) { fprintf(stderr, "dsi: Can't open %s\n", tmpFile); goto error; } line = 0; for (ip = inBuf; *ip; ip++) { start = ip; if (dsiFp == 0) { if (*ip == '\n') { /* Remove duplicate new lines */ while (ip[1] == '\n') { ip++; } fputc(*ip, ofp); line++; continue; } if (*ip != '<' || ip[1] != '!' || ip[2] != '-' || ip[3] != '-') { fputc(*ip, ofp); continue; } tok = "<!-- BeginDsi \""; len = strlen(tok); if (strncmp(start, tok, strlen(tok)) == 0) { /* * Cleanup if file has been corrupted by HTML editors */ if (start > inBuf && start[-1] != '\n') { fprintf(ofp, "\n"); } startDsi = start; start += len - 1; end = getNextTok(dsiName, sizeof(dsiName), start); if (end == 0) { fprintf(stderr, "dsi: Syntax error for DSI in %s at line %d\n", path, line); goto error; } for (start = end; *start && isspace((int) *start); start++); /* Parse any pattern match args "searchPattern" "trueReplace" "falseReplace" */ if (*start == '"') { start = getNextTok(searchPat, sizeof(searchPat), start); start = getNextTok(truePat, sizeof(truePat), start); start = getNextTok(falsePat, sizeof(falsePat), start); } if (start == 0) { fprintf(stderr, "dsi: Syntax error for DSI in %s at line %d\n", path, line); goto error; } for (; *start && isspace((int) *start); start++); end = strstr(start, "-->"); if (end == 0) { fprintf(stderr, "dsi: Missing closing comment in %s at line %d\n", path, line); goto error; } c = end[3]; end[3] = '\0'; fprintf(ofp, "%s\n", startDsi); end[3] = c; if (dsiName[0] != '/') { sprintf(dsiPath, "%s/%s", incDir, dsiName); } else { strcpy(dsiPath, dsiName); } dsiFp = fopen(dsiPath, "r" MPR_TEXT); if (dsiFp == 0) { fprintf(stderr, "dsi: Can't open DSI %s. Referenced in %s at line %d\n", dsiPath, path, line); goto error; } stat(dsiPath, &sbuf); if (verbose > 1) { printf(" DSI %s\n", dsiPath); } ip = &end[2]; } else { fputc(*ip, ofp); } } else { tok = "<!-- EndDsi -->"; len = strlen(tok); if (strncmp(start, tok, strlen(tok)) == 0) { dsiBuf = (char*) malloc((int) sbuf.st_size + 1); rc = fread(dsiBuf, 1, (int) sbuf.st_size, dsiFp); if (rc < 0) { fprintf(stderr, "dsi: Can't read DSI %s\n", dsiPath); return -1; } dsiBuf[rc] = '\0'; fclose(dsiFp); dsiFp = 0; patched++; if (level == 0 && 0) { rc = fwrite(dsiBuf, 1, rc, ofp); } else { for (cp = dsiBuf; *cp; ) { /* This is a very fragile parser. It really needs to be more flexible. */ /* <a href= <link .... href= */ if (matchLink(ofp, " href=\"", &cp)) { continue; } if (matchLink(ofp, "\thref=\"", &cp)) { continue; } /* <img src= <script ... src= */ if (matchLink(ofp, " src=\"", &cp)) { continue; } if (matchLink(ofp, "\tsrc=\"", &cp)) { continue; } /* <form ... action= */ if (matchLink(ofp, "action=\"", &cp)) { continue; } /* _ROOT_ = " */ if (matchLink(ofp, "_ROOT_=\"", &cp)) { continue; } /* Special _DSI_ pattern editing */ tag = "_DSI_"; len = strlen(tag); if (strncmp(cp, tag, len) == 0) { cp += len - 1; ep = strchr(cp, '"'); if (strncmp(cp, searchPat, strlen(searchPat)) == 0){ fprintf(ofp, "%s\"", truePat); } else { fprintf(ofp, "%s\"", falsePat); } cp = ep + 1; continue; } /* Javascript patches */ ext = strchr(dsiPath, '.'); if (ext && strcmp(ext, ".js") == 0) { /* = / *DSI* / " */ if (matchLink(ofp, "= /*DSI*/ \"", &cp)) { continue; } /* src = ' */ if (matchLink(ofp, "src == '", &cp)) { continue; } } fputc(*cp, ofp); cp++; } } fprintf(ofp, "%s", tok); ip = &start[strlen(tok)]; /* Cleanup if file has been corrupted by HTML editors */ if (ip[1] != '\0' && ip[2] != '\0' && ip[2] != '\n') { fputc('\n', ofp); } } else { /* Don't output as it is being replaced with DSI content */ } } } fclose(ifp); if (! patched) { fclose(ofp); unlink(tmpFile); } else { /* * If we found a DSI in the file, rename the patched file */ fclose(ofp); sprintf(saveFile, "%s.dsiSave", path); unlink(saveFile); chmod(path, 0755); rename(path, saveFile); if (rename(tmpFile, path) < 0) { fprintf(stderr, "dsi: Can't rename %s to %s\n", tmpFile, path); rename(saveFile, path); return -1; } unlink(saveFile); } return 0; error: if (ifp) { fclose(ifp); } if (ofp) { fclose(ofp); } if (inBuf) { free(inBuf); } if (dsiBuf) { free(dsiBuf); } return -1; }
int SFReadHdr(FILE *file, SFSTRUCT *snd, int infoBmax) /* utility to sample the header of an opened file, at most infobmax info byts */ { #define LBLEN 256 char lbuf[LBLEN]; int nhdread = 0; int hdtotlen = 0; int done = 0; int schan = 0; long samps = 0; int srate = 0; int snbyt = 0; int sbits = 0; int basefmt = _LINEAR; long ft; char *ib_ptr; int bytemode = BM_INORDER; int seekable = TRUE; int skipmagic = 0; ft = ftell(file); if( ft < 0 ) { /* don't try seek on stdin */ /* pipe - skip magic if already ID'd */ if (GetSFFType(file) != NULL) { #ifdef HAVE_FPUSH /* If we have fpush, we'll have pushed back to zero anyway */ skipmagic = 0; #else /* !HAVE_FPUSH */ /* we'll guess that the type came from SFIdentify, although it *could* have come from SFSetFileType, in which case we'll fail */ skipmagic = sizeof(INT32); #endif /* HAVE_FPUSH */ } seekable = FALSE; } else if (ft == sizeof(INT32)) { /* assume we already read the magic & fake it up */ skipmagic = ft; } else { if(fseek(file,(long)0,SEEK_SET) != 0 ) /* move to start of file */ return(SFerror = SFE_RDERR); } if(skipmagic) strncpy(lbuf, "NIST", skipmagic); /* fgets(lbuf+skipmagic, LBLEN-skipmagic, file); nhdread += strlen(lbuf); chop(lbuf); */ /* Use fread rather than fgets for this first read because the 4 bytes 'pushed back' by SFIdentify are only restored in my_fread - not in my_fgets */ nhdread = skipmagic; nhdread += fread(lbuf+skipmagic, 1, strlen("NIST_1A/") - skipmagic, file); /* if we're at EOF, it's not a sound file (lame attempt to readon strem) */ if (feof(file)) { return (SFerror = SFE_EOF); } lbuf[8] = '\0'; chop(lbuf); if(strcmp(lbuf, "NIST_1A")!=0) { fprintf(stderr, "Error: NIST SFRdHdr: id of '%s' is not 'NIST_1A'\n", lbuf); return SFE_NSF; /* Not a Sound File */ } /* read header values */ /* first line is number of bytes in header */ fgets(lbuf, LBLEN, file); nhdread += strlen(lbuf); chop(lbuf); hdtotlen = atoi(lbuf); /* rest are token/value pairs */ /* reset the info_buf used to store unknown fields */ /* 2002-10-08: allocate if not yet, or too small */ if (ib_len < hdtotlen) { if (info_buf) free(info_buf); info_buf = NULL; } if (info_buf == NULL) { ib_len = hdtotlen; info_buf = malloc(ib_len); } info_buf[0] = '\0'; ib_ptr = info_buf; while(!done && !feof(file)) { char tok[LBLEN], *t; int tklen; t = lbuf; fgets(lbuf, LBLEN, file); nhdread += strlen(lbuf); chop(lbuf); /* fprintf(stderr, "HDR: got '%s'\n", lbuf); */ tklen = getNextTok(&t, tok); if(strcmp(tok, "end_head")==0) { done = 1; } else if(strcmp(tok, "channel_count")==0) { tklen = getNextTok(&t, tok); /* format spec - -i */ tklen = getNextTok(&t, tok); /* actual count */ schan = atoi(tok); } else if(strcmp(tok, "sample_coding")==0) { tklen = getNextTok(&t, tok); /* format spec - -sN */ tklen = getNextTok(&t, tok); /* actual coding */ if(strcmp(tok, "pcm")==0 || strcmp(tok, "linear")==0) { basefmt |= _LINEAR; } else if(strncmp(tok, "pcm,",4)==0) { basefmt |= _LINEAR; /* check for shorten (any version 2.xx) */ if (strncmp(tok+4, "embedded-shorten-v2.", 20)==0) { /* this is embedded shorten - hope we are decoding it */ } else { fprintf(stderr, "Warn: NIST Hdr: Extra coding '%s' ignored\n", tok+4); } } else if(strcmp(tok, "alaw")==0) { basefmt |= _ALAW; } else if(strcmp(tok, "ulaw")==0) { basefmt |= _ULAW; } else if(strncmp(tok, "ulaw",4)==0) { basefmt |= _ULAW; fprintf(stderr, "Warn: NIST Hdr: Extra coding '%s' ignored\n", tok+4); } else if(strcmp(tok, "mu-law")==0) { basefmt |= _ULAW; } else if(strcmp(tok, "float")==0) { basefmt |= _FLOAT; } else if(strcmp(tok, "raw")==0) { /* 2005-03-15: SRI's hacked format holds floats as 'raw' */ basefmt |= _FLOAT; /* .. and has an implied byte order */ bytemode = BM_BYWDREV; } else { fprintf(stderr, "Warn: NIST Hdr: '%s' not pcm, alaw, ulaw or mu-law (assume pcm)\n", tok); } } else if(strcmp(tok, "sample_count")==0) { tklen = getNextTok(&t, tok); /* format spec - -i */ tklen = getNextTok(&t, tok); /* actual count */ samps = atol(tok); } else if(strcmp(tok, "sample_rate")==0) { tklen = getNextTok(&t, tok); /* format spec - -i */ tklen = getNextTok(&t, tok); /* actual count */ srate = atol(tok); } else if(strcmp(tok, "sample_n_bytes")==0) { tklen = getNextTok(&t, tok); /* format spec - -i */ tklen = getNextTok(&t, tok); /* actual count */ snbyt = atoi(tok); } else if(strcmp(tok, "sample_byte_format")==0) { tklen = getNextTok(&t, tok); tklen = getNextTok(&t, tok); if(strcmp(tok, "01")==0 || strcmp(tok, "0123")==0) { bytemode = BM_BYTEREV; /* fprintf(stderr,"this data is byteswapped, but I can't handle it\n"); */ } else if(strcmp(tok, "10")==0 || strcmp(tok, "3210")==0) { bytemode = BM_INORDER; } else if(strcmp(tok, "1")==0) { /* mu-law reported like this? */ bytemode = BM_INORDER; } else if(strcmp(tok, "mu-law")==0) { bytemode = BM_INORDER; basefmt |= _ULAW; /* fprintf(stderr, "NIST SFRdHdr: funky mu-law sample_byte_format\n"); */ } else { fprintf(stderr, "Warn: NIST Hdr: sample_byte_format '%s' is not mu-law, 10 or 01 (assume 10)\n", tok); } } else if(strcmp(tok, "sample_sig_bits")==0) { tklen = getNextTok(&t, tok); /* format spec - -i */ tklen = getNextTok(&t, tok); /* actual count */ sbits = atoi(tok); } else if(strcmp(tok, "sample_checksum")==0) { long cksum; tklen = getNextTok(&t, tok); /* format spec - -i */ tklen = getNextTok(&t, tok); /* actual count */ cksum = atoi(tok); /* just consume & ignore */ } else { /* not an anticipated field - write into the info_buf */ if(strlen(lbuf)) { sprintf(ib_ptr, "%s\n", lbuf); ib_ptr += strlen(ib_ptr); /* hope info_buf never fills up! */ } } } if(!done) { /* hit eof before completing */ fprintf(stderr, "Error: NIST Hdr: looked good, but no end_head\n"); return SFE_NSF; } if(sbits != 0 && sbits != 8 * snbyt) { fprintf(stderr, "Warn: NIST Hdr: %d bits a surprise for %d bytes/samp (using %d bytes/samp)\n", sbits, snbyt, snbyt); } /* handle whatever happened to bytemode */ if(snbyt>1 && (bytemode & BM_WORDMASK) != (HostByteMode() & BM_WORDMASK)) { if (snbyt > 2) SetBytemode(file, BM_BYWDREV); else SetBytemode(file, BM_BYTEREV); } else { /* set the flag that no byteswapping is needed */ SetBytemode(file, BM_INORDER); } if(nhdread > hdtotlen) { fprintf(stderr, "Error: NIST Hdr: overran header len of %d bytes - expect stack corruption\n", hdtotlen); return SFE_NSF; } if(seekable) { fseek(file, hdtotlen, SEEK_SET); } else { seek_by_read(file, hdtotlen-nhdread); } /* now at start of data */ /* set up fields */ snd->magic = SFMAGIC; snd->headBsize = sizeof(SFSTRUCT); assert(snbyt==8 || snbyt==4 ||snbyt==2 || snbyt==1); /* ulw, lin8 or lin16, float or double */ /* snd->format = basefmt | ((snbyt==1)?SFMT_CHAR:SFMT_SHORT); */ snd->format = basefmt | snbyt; /* luckily, _EIGHTBYTE==8 */ snd->channels = schan; snd->samplingRate = (float)srate; snd->dataBsize = snbyt*samps*schan; /* samps is frames now 1999sep28 */ { /* handle whatever we put into info_buf */ int ibSize = ib_ptr - info_buf; int lastwd = ibSize % 4; if(infoBmax <= 0) infoBmax = SFDFLTBYTS; snd->info[0] = '\0'; if(lastwd) { /* pad last word to 4-byte boundary with zeros */ int xtra = 4-lastwd; long l = 0; memcpy(info_buf+ibSize, &l, xtra); ibSize += xtra; } memcpy(snd->info, info_buf, MIN(infoBmax, ibSize)); snd->headBsize += MAX(0, ibSize-SFDFLTBYTS); } /* record the indicated seek points for start and end of sound data */ SetSeekEnds(file, hdtotlen, hdtotlen+snd->dataBsize); return SFE_OK; }