// |decode_mime_part2_str| taken from comi18n.c // Decode RFC2047-encoded words in the input and convert the result to UTF-8. // If aOverrideCharset is true, charset in RFC2047-encoded words is // ignored and aDefaultCharset is assumed, instead. aDefaultCharset // is also used to convert raw octets (without RFC 2047 encoding) to UTF-8. //static nsresult DecodeRFC2047Str(const char *aHeader, const char *aDefaultCharset, bool aOverrideCharset, nsACString &aResult) { const char *p, *q, *r; char *decodedText; const char *begin; // tracking pointer for where we are in the input buffer PRInt32 isLastEncodedWord = 0; const char *charsetStart, *charsetEnd; char charset[80]; // initialize charset name to an empty string charset[0] = '\0'; begin = aHeader; // To avoid buffer realloc, if possible, set capacity in advance. No // matter what, more than 3x expansion can never happen for all charsets // supported by Mozilla. SCSU/BCSU with the sliding window set to a // non-BMP block may be exceptions, but Mozilla does not support them. // Neither any known mail/news program use them. Even if there's, we're // safe because we don't use a raw *char any more. aResult.SetCapacity(3 * strlen(aHeader)); while ((p = PL_strstr(begin, "=?")) != 0) { if (isLastEncodedWord) { // See if it's all whitespace. for (q = begin; q < p; ++q) { if (!PL_strchr(" \t\r\n", *q)) break; } } if (!isLastEncodedWord || q < p) { // copy the part before the encoded-word CopyRawHeader(begin, p - begin, aDefaultCharset, aResult); begin = p; } p += 2; // Get charset info charsetStart = p; charsetEnd = 0; for (q = p; *q != '?'; q++) { if (*q <= ' ' || PL_strchr(especials, *q)) { goto badsyntax; } // RFC 2231 section 5 if (!charsetEnd && *q == '*') { charsetEnd = q; } } if (!charsetEnd) { charsetEnd = q; } // Check for too-long charset name if (PRUint32(charsetEnd - charsetStart) >= sizeof(charset)) goto badsyntax; memcpy(charset, charsetStart, charsetEnd - charsetStart); charset[charsetEnd - charsetStart] = 0; q++; if (*q != 'Q' && *q != 'q' && *q != 'B' && *q != 'b') goto badsyntax; if (q[1] != '?') goto badsyntax; r = q; for (r = q + 2; *r != '?'; r++) { if (*r < ' ') goto badsyntax; } if (r[1] != '=') goto badsyntax; else if (r == q + 2) { // it's empty, skip begin = r + 2; isLastEncodedWord = 1; continue; } if(*q == 'Q' || *q == 'q') decodedText = DecodeQ(q + 2, r - (q + 2)); else { // bug 227290. ignore an extraneous '=' at the end. // (# of characters in B-encoded part has to be a multiple of 4) PRInt32 n = r - (q + 2); n -= (n % 4 == 1 && !PL_strncmp(r - 3, "===", 3)) ? 1 : 0; decodedText = PL_Base64Decode(q + 2, n, nsnull); } if (decodedText == nsnull) goto badsyntax; // Override charset if requested. Never override labeled UTF-8. // Use default charset instead of UNKNOWN-8BIT if ((aOverrideCharset && 0 != nsCRT::strcasecmp(charset, "UTF-8")) || (aDefaultCharset && 0 == nsCRT::strcasecmp(charset, "UNKNOWN-8BIT"))) { PL_strncpy(charset, aDefaultCharset, sizeof(charset) - 1); charset[sizeof(charset) - 1] = '\0'; } { nsCOMPtr<nsIUTF8ConverterService> cvtUTF8(do_GetService(NS_UTF8CONVERTERSERVICE_CONTRACTID)); nsCAutoString utf8Text; // skip ASCIIness/UTF8ness test if aCharset is 7bit non-ascii charset. if (cvtUTF8 && NS_SUCCEEDED( cvtUTF8->ConvertStringToUTF8(nsDependentCString(decodedText), charset, IS_7BIT_NON_ASCII_CHARSET(charset), utf8Text))) { aResult.Append(utf8Text); } else { aResult.Append(REPLACEMENT_CHAR); } } PR_Free(decodedText); begin = r + 2; isLastEncodedWord = 1; continue; badsyntax: // copy the part before the encoded-word aResult.Append(begin, p - begin); begin = p; isLastEncodedWord = 0; } // put the tail back CopyRawHeader(begin, strlen(begin), aDefaultCharset, aResult); nsCAutoString tempStr(aResult); tempStr.ReplaceChar('\t', ' '); aResult = tempStr; return NS_OK; }
void CFileDetailDialog::OnBnClickedButtonStrip(wxCommandEvent& WXUNUSED(evt)) { wxString filename; filename = CastChild(IDC_FILENAME, wxTextCtrl)->GetValue(); int extpos = filename.Find('.', true); wxString ext; if (extpos > 0) { // get the extension - we do not modify it except make it lowercase ext = filename.Mid(extpos); ext.MakeLower(); // get rid of extension and replace . with space filename.Truncate(extpos); filename.Replace(wxT("."),wxT(" ")); } // Replace Space-holders with Spaces filename.Replace(wxT("_"),wxT(" ")); filename.Replace(wxT("%20"),wxT(" ")); // Some additional formatting filename.Replace(wxT("hYPNOTiC"), wxEmptyString); filename.MakeLower(); filename.Replace(wxT("xxx"), wxT("XXX")); // filename.Replace(wxT("xdmnx"), wxEmptyString); // filename.Replace(wxT("pmp"), wxEmptyString); // filename.Replace(wxT("dws"), wxEmptyString); filename.Replace(wxT("www pornreactor com"), wxEmptyString); filename.Replace(wxT("sharereactor"), wxEmptyString); filename.Replace(wxT("found via www filedonkey com"), wxEmptyString); filename.Replace(wxT("deviance"), wxEmptyString); filename.Replace(wxT("adunanza"), wxEmptyString); filename.Replace(wxT("-ftv"), wxEmptyString); filename.Replace(wxT("flt"), wxEmptyString); filename.Replace(wxT("[]"), wxEmptyString); filename.Replace(wxT("()"), wxEmptyString); // Change CD, CD#, VCD{,#}, DVD{,#}, ISO, PC to uppercase ReplaceWord(filename, wxT("cd"), wxT("CD"), true); ReplaceWord(filename, wxT("vcd"), wxT("VCD"), true); ReplaceWord(filename, wxT("dvd"), wxT("DVD"), true); ReplaceWord(filename, wxT("iso"), wxT("ISO"), false); ReplaceWord(filename, wxT("pc"), wxT("PC"), false); // Make leading Caps // and delete 1+ spaces if (filename.Length()>1) { bool last_char_space = true; bool last_char_wordseparator = true; unsigned int i = 0; do { wxChar c = filename.GetChar(i); if (c == ' ') { if (last_char_space) { filename.Remove(i, 1); i--; } else { last_char_space = true; } } else if (c == '.') { if (last_char_space && i > 0) { i--; filename.Remove(i, 1); } last_char_space = false; } else { if (last_char_wordseparator) { wxString tempStr(c); tempStr.MakeUpper(); filename.SetChar(i, tempStr.GetChar(0)); last_char_space = false; } } last_char_wordseparator = IsWordSeparator(c); i++; } while (i < filename.Length()); if (last_char_space && i > 0) { filename.Remove(i-1, 1); } } // should stay lowercase ReplaceWord(filename, wxT("By"), wxT("by")); // re-add extension filename += ext; setValueForFilenameTextEdit(filename); }
nsresult nsMIMEHeaderParamImpl::DoParameterInternal(const char *aHeaderValue, const char *aParamName, ParamDecoding aDecoding, char **aCharset, char **aLang, char **aResult) { if (!aHeaderValue || !*aHeaderValue || !aResult) return NS_ERROR_INVALID_ARG; *aResult = nsnull; if (aCharset) *aCharset = nsnull; if (aLang) *aLang = nsnull; const char *str = aHeaderValue; // skip leading white space. for (; *str && nsCRT::IsAsciiSpace(*str); ++str) ; const char *start = str; // aParamName is empty. return the first (possibly) _unnamed_ 'parameter' // For instance, return 'inline' in the following case: // Content-Disposition: inline; filename=..... if (!aParamName || !*aParamName) { for (; *str && *str != ';' && !nsCRT::IsAsciiSpace(*str); ++str) ; if (str == start) return NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY; *aResult = (char *) nsMemory::Clone(start, (str - start) + 1); NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); (*aResult)[str - start] = '\0'; // null-terminate return NS_OK; } /* Skip forward to first ';' */ for (; *str && *str != ';' && *str != ','; ++str) ; if (*str) str++; /* Skip over following whitespace */ for (; *str && nsCRT::IsAsciiSpace(*str); ++str) ; // Some broken http servers just specify parameters // like 'filename' without specifying disposition // method. Rewind to the first non-white-space // character. if (!*str) str = start; // RFC2231 - The legitimate parm format can be: // A. title=ThisIsTitle // B. title*=us-ascii'en-us'This%20is%20wierd. // C. title*0*=us-ascii'en'This%20is%20wierd.%20We // title*1*=have%20to%20support%20this. // title*2="Else..." // D. title*0="Hey, what you think you are doing?" // title*1="There is no charset and lang info." // RFC5987: only A and B PRInt32 paramLen = strlen(aParamName); bool haveCaseAValue = false; PRInt32 nextContinuation = 0; // next value in series, or -1 if error while (*str) { const char *tokenStart = str; const char *tokenEnd = 0; const char *valueStart = str; const char *valueEnd = 0; bool seenEquals = false; NS_ASSERTION(!nsCRT::IsAsciiSpace(*str), "should be after whitespace."); // Skip forward to the end of this token. for (; *str && !nsCRT::IsAsciiSpace(*str) && *str != '=' && *str != ';'; str++) ; tokenEnd = str; // Skip over whitespace, '=', and whitespace while (nsCRT::IsAsciiSpace(*str)) ++str; if (*str == '=') { ++str; seenEquals = true; } while (nsCRT::IsAsciiSpace(*str)) ++str; bool needUnquote = false; if (*str != '"') { // The value is a token, not a quoted string. valueStart = str; for (valueEnd = str; *valueEnd && !nsCRT::IsAsciiSpace (*valueEnd) && *valueEnd != ';'; valueEnd++) ; str = valueEnd; } else { // The value is a quoted string. needUnquote = true; ++str; valueStart = str; for (valueEnd = str; *valueEnd; ++valueEnd) { if (*valueEnd == '\\') ++valueEnd; else if (*valueEnd == '"') break; } str = valueEnd + 1; } // See if this is the simplest case (case A above), // a 'single' line value with no charset and lang. // If so, copy it and return. if (tokenEnd - tokenStart == paramLen && seenEquals && !nsCRT::strncasecmp(tokenStart, aParamName, paramLen)) { if (*aResult) { // either seen earlier caseA value already--we prefer first--or caseA // came after a continuation: either way, prefer other value goto increment_str; } // if the parameter spans across multiple lines we have to strip out the // line continuation -- jht 4/29/98 nsCAutoString tempStr(valueStart, valueEnd - valueStart); tempStr.StripChars("\r\n"); char *res = ToNewCString(tempStr); NS_ENSURE_TRUE(res, NS_ERROR_OUT_OF_MEMORY); if (needUnquote) RemoveQuotedStringEscapes(res); *aResult = res; haveCaseAValue = true; // keep going, we may find a RFC 2231/5987 encoded alternative } // case B, C, and D else if (tokenEnd - tokenStart > paramLen && !nsCRT::strncasecmp(tokenStart, aParamName, paramLen) && seenEquals && *(tokenStart + paramLen) == '*') { const char *cp = tokenStart + paramLen + 1; // 1st char past '*' bool needUnescape = *(tokenEnd - 1) == '*'; bool caseB = (tokenEnd - tokenStart) == paramLen + 1; bool caseCorDStart = (*cp == '0') && needUnescape; bool acceptContinuations = (aDecoding != RFC_5987_DECODING); // CaseB and start of CaseC: requires charset and optional language // in quotes (quotes required even if lang is blank) if (caseB || (caseCorDStart && acceptContinuations)) { if (caseCorDStart) { if (nextContinuation++ != 0) { // error: already started a continuation. Skip future // continuations and return whatever initial parts were in order. nextContinuation = -1; goto increment_str; } } // look for single quotation mark(') const char *sQuote1 = PL_strchr(valueStart, 0x27); const char *sQuote2 = (char *) (sQuote1 ? PL_strchr(sQuote1 + 1, 0x27) : nsnull); // Two single quotation marks must be present even in // absence of charset and lang. if (!sQuote1 || !sQuote2) { // log the warning and skip to next parameter NS_WARNING("Mandatory two single quotes are missing in header parameter, parameter ignored\n"); goto increment_str; } // charset part is required if (! (sQuote1 > valueStart && sQuote1 < valueEnd)) { // log the warning and skip to next parameter NS_WARNING("Mandatory charset part missing in header parameter, parameter ignored\n"); goto increment_str; } if (aCharset) { *aCharset = (char *) nsMemory::Clone(valueStart, sQuote1 - valueStart + 1); if (*aCharset) *(*aCharset + (sQuote1 - valueStart)) = 0; } if (aLang && sQuote2 > sQuote1 + 1 && sQuote2 < valueEnd) { *aLang = (char *) nsMemory::Clone(sQuote1 + 1, sQuote2 - (sQuote1 + 1) + 1); if (*aLang) *(*aLang + (sQuote2 - (sQuote1 + 1))) = 0; } if (sQuote2 + 1 < valueEnd) { if (*aResult) { // caseA value already read, or caseC/D value already read // but we're now reading caseB: either way, drop old value nsMemory::Free(*aResult); haveCaseAValue = false; } *aResult = (char *) nsMemory::Alloc(valueEnd - (sQuote2 + 1) + 1); if (*aResult) { memcpy(*aResult, sQuote2 + 1, valueEnd - (sQuote2 + 1)); *(*aResult + (valueEnd - (sQuote2 + 1))) = 0; if (needUnescape) { nsUnescape(*aResult); if (caseB) return NS_OK; // caseB wins over everything else } } } } // end of if-block : title*0*= or title*= // caseD: a line of multiline param with no need for unescaping : title*[0-9]= // or 2nd or later lines of a caseC param : title*[1-9]*= else if (acceptContinuations && nsCRT::IsAsciiDigit(PRUnichar(*cp))) { PRInt32 nextSegment = atoi(cp); // no leading zeros allowed except for ... position 0 bool broken = nextSegment > 0 && *cp == '0'; if (broken || nextSegment != nextContinuation++) { // error: gap in continuation or unneccessary leading 0. // Skip future continuations and return whatever initial parts were // in order. nextContinuation = -1; goto increment_str; } if (haveCaseAValue && *aResult) { // drop caseA value nsMemory::Free(*aResult); *aResult = 0; haveCaseAValue = false; } PRInt32 len = 0; if (*aResult) // 2nd or later lines of multiline parameter { len = strlen(*aResult); char *ns = (char *) nsMemory::Realloc(*aResult, len + (valueEnd - valueStart) + 1); if (!ns) { nsMemory::Free(*aResult); } *aResult = ns; } else { NS_ASSERTION(*cp == '0', "Not first value in continuation"); // must be; 1st line : title*0= *aResult = (char *) nsMemory::Alloc(valueEnd - valueStart + 1); } if (*aResult) { // append a partial value memcpy(*aResult + len, valueStart, valueEnd - valueStart); *(*aResult + len + (valueEnd - valueStart)) = 0; if (needUnescape) nsUnescape(*aResult + len); } else return NS_ERROR_OUT_OF_MEMORY; } // end of if-block : title*[0-9]= or title*[1-9]*= } // str now points after the end of the value. // skip over whitespace, ';', whitespace. increment_str: while (nsCRT::IsAsciiSpace(*str)) ++str; if (*str == ';') ++str; while (nsCRT::IsAsciiSpace(*str)) ++str; } if (*aResult) return NS_OK; else return NS_ERROR_INVALID_ARG; // aParameter not found !! }
int LDSBandwidth::setupCL(void) { cl_int status = 0; cl_device_type dType; if(sampleArgs->deviceType.compare("cpu") == 0) { dType = CL_DEVICE_TYPE_CPU; } else //deviceType = "gpu" { dType = CL_DEVICE_TYPE_GPU; if(sampleArgs->isThereGPU() == false) { std::cout << "GPU not found. Falling back to CPU device" << std::endl; dType = CL_DEVICE_TYPE_CPU; } } /* * Have a look at the available platforms and pick either * the AMD one if available or a reasonable default. */ cl_platform_id platform = NULL; int retValue = getPlatform(platform, sampleArgs->platformId, sampleArgs->isPlatformEnabled()); CHECK_ERROR(retValue, SDK_SUCCESS, "getPlatform() failed"); // Display available devices. retValue = displayDevices(platform, dType); CHECK_ERROR(retValue, SDK_SUCCESS, "displayDevices() failed"); /* * If we could find our platform, use it. Otherwise use just available platform. */ cl_context_properties cps[3] = { CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 }; context = clCreateContextFromType(cps, dType, NULL, NULL, &status); CHECK_OPENCL_ERROR(status, "clCreateContextFromType failed."); // getting device on which to run the sample status = getDevices(context, &devices, sampleArgs->deviceId, sampleArgs->isDeviceIdEnabled()); CHECK_ERROR(status, SDK_SUCCESS, "getDevices() failed"); //Set device info of given cl_device_id retValue = deviceInfo.setDeviceInfo(devices[sampleArgs->deviceId]); CHECK_ERROR(retValue, SDK_SUCCESS, "SDKDeviceInfo::setDeviceInfo() failed"); std::string deviceStr(deviceInfo.deviceVersion); size_t vStart = deviceStr.find(" ", 0); size_t vEnd = deviceStr.find(" ", vStart + 1); std::string vStrVal = deviceStr.substr(vStart + 1, vEnd - vStart - 1); #ifdef CL_VERSION_1_1 if(vStrVal.compare("1.0") > 0) { char openclVersion[1024]; status = clGetDeviceInfo(devices[sampleArgs->deviceId], CL_DEVICE_OPENCL_C_VERSION, sizeof(openclVersion), openclVersion, 0); CHECK_OPENCL_ERROR(status, "clGetDeviceInfo failed."); std::string tempStr(openclVersion); size_t dotPos = tempStr.find_first_of("."); size_t spacePos = tempStr.find_last_of(" "); tempStr = tempStr.substr(dotPos + 1, spacePos - dotPos); int minorVersion = atoi(tempStr.c_str()); // OpenCL 1.1 has inbuilt support for vec3 data types if(minorVersion < 1 && vec3 == true) { OPENCL_EXPECTED_ERROR("Device doesn't support built-in 3 component vectors!"); } } else { // OpenCL 1.1 has inbuilt support for vec3 data types if(vec3 == true) { OPENCL_EXPECTED_ERROR("Device doesn't support built-in 3 component vectors!"); } } #else // OpenCL 1.1 has inbuilt support for vec3 data types if(vec3 == true) { OPENCL_EXPECTED_ERROR("Device doesn't support built-in 3 component vectors!"); } #endif { // The block is to move the declaration of prop closer to its use cl_command_queue_properties prop = 0; prop |= CL_QUEUE_PROFILING_ENABLE; commandQueue = clCreateCommandQueue(context, devices[sampleArgs->deviceId], prop, &status); CHECK_OPENCL_ERROR(status, "clCreateCommandQueue failed."); } outputBuffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_float) * vectorSize * length, 0, &status); CHECK_OPENCL_ERROR(status, "clCreateBuffer failed. (outputBuffer)"); // create a CL program using the kernel source char buildOption[64]; if(vectorSize == 1) { sprintf(buildOption, "-D DATATYPE=float "); } else { sprintf(buildOption, "-D DATATYPE=float%d ", vec3 == true ? 3 : vectorSize); } buildProgramData buildData; buildData.kernelName = std::string("LDSBandwidth_Kernels.cl"); buildData.devices = devices; buildData.deviceId = sampleArgs->deviceId; buildData.flagsStr = std::string(buildOption); if(sampleArgs->isLoadBinaryEnabled()) { buildData.binaryName = std::string(sampleArgs->loadBinary.c_str()); } if(sampleArgs->isComplierFlagsSpecified()) { buildData.flagsFileName = std::string(sampleArgs->flags.c_str()); } retValue = buildOpenCLProgram(program, context, buildData); CHECK_ERROR(retValue, SDK_SUCCESS, "buildOpenCLProgram() failed"); // ConstantBuffer bandwidth from single access kernel[0] = clCreateKernel(program, "LDSBandwidth_single", &status); CHECK_OPENCL_ERROR(status, "clCreateKernel failed.(LDSBandwidth_single)"); // ConstantBuffer bandwidth from linear access kernel[1] = clCreateKernel(program, "LDSBandwidth_linear", &status); CHECK_OPENCL_ERROR(status, "clCreateKernel failed.(LDSBandwidth_linear)"); kernel[2] = clCreateKernel(program, "LDSBandwidth_single_verify", &status); CHECK_OPENCL_ERROR(status, "clCreateKernel failed.(LDSBandwidth_single_verify)"); kernel[3] = clCreateKernel(program, "LDSBandwidth_linear_verify", &status); CHECK_OPENCL_ERROR(status, "clCreateKernel failed.(LDSBandwidth_linear_verify)"); kernel[4] = clCreateKernel(program, "LDSBandwidth_write_linear", &status); CHECK_OPENCL_ERROR(status, "clCreateKernel failed.(LDSBandwidth_linear_verify)"); kernel[5] = clCreateKernel(program, "LDSBandwidth_write_linear_verify", &status); CHECK_OPENCL_ERROR(status, "clCreateKernel failed.(LDSBandwidth_linear_verify)"); return SDK_SUCCESS; }
MStatus vixo_visImport::compute( const MPlug& plug, MDataBlock& data ) { MStatus stat=MS::kSuccess; if(plug.array()!=vis) return MS::kSuccess; //cout<<plug.info().asChar()<<endl; int objIdx=plug.logicalIndex(); MDataHandle file_handle=data.inputValue(file); MString filename=file_handle.asString(); MDataHandle timeHandle=data.inputValue(time); int t=timeHandle.asTime().as(MTime::Unit::kFilm); if(mapObjName.count(objIdx)<=0) return MS::kSuccess; //cout<<"test"<<endl; MString objNameValue(mapObjName.find(objIdx)->second.c_str()); bool res=true; ifstream fin(filename.asChar(),ios_base::in|ios_base::binary); if(fin.fail()) { MDataHandle eleHandle=data.outputValue(plug); eleHandle.set(res); data.setClean(plug); return MS::kSuccess; } int objNum=0; fin.read((char*)&objNum,sizeof(int)); vector<struct_visBasicInfo> objIndexes(objNum); fin.read((char*)&objIndexes[0],sizeof(struct_visBasicInfo)*objNum); int fileObjIndex=-1; for(int i=0;i<objNum;i++) { MStringArray tempArr; MString tempStr(objIndexes[i].objName); tempStr.split(':',tempArr); if(tempArr[tempArr.length()-1]==objNameValue) { fileObjIndex=i; break; } } if(fileObjIndex==-1) { MDataHandle eleHandle=data.outputValue(plug); eleHandle.set(res); data.setClean(plug); fin.close(); return MS::kSuccess; } //cout<<"test1"<<endl; if(t<objIndexes[fileObjIndex].startFrame||t>objIndexes[fileObjIndex].endFrame) { fin.close(); MDataHandle eleHandle=data.outputValue(plug); eleHandle.set(res); data.setClean(plug); return MS::kSuccess; } //cout<<"test2"<<endl; fin.seekg(objIndexes[fileObjIndex].visBegin.operator+(sizeof(char)*(t-objIndexes[fileObjIndex].startFrame))); char value; fin.read((char *)&value,sizeof(char)); fin.close(); //cout<<t<<" "<<(int)value<<endl; if(value==0) res=0; MDataHandle eleHandle=data.outputValue(plug); eleHandle.set(res); data.setClean(plug); return MS::kSuccess; }
// moved almost verbatim from mimehdrs.cpp // char * // MimeHeaders_get_parameter (const char *header_value, const char *parm_name, // char **charset, char **language) // // The format of these header lines is // <token> [ ';' <token> '=' <token-or-quoted-string> ]* NS_IMETHODIMP nsMIMEHeaderParamImpl::GetParameterInternal(const char *aHeaderValue, const char *aParamName, char **aCharset, char **aLang, char **aResult) { if (!aHeaderValue || !*aHeaderValue || !aResult) return NS_ERROR_INVALID_ARG; *aResult = nsnull; if (aCharset) *aCharset = nsnull; if (aLang) *aLang = nsnull; const char *str = aHeaderValue; // skip leading white space. for (; *str && nsCRT::IsAsciiSpace(*str); ++str) ; const char *start = str; // aParamName is empty. return the first (possibly) _unnamed_ 'parameter' // For instance, return 'inline' in the following case: // Content-Disposition: inline; filename=..... if (!aParamName || !*aParamName) { for (; *str && *str != ';' && !nsCRT::IsAsciiSpace(*str); ++str) ; if (str == start) return NS_ERROR_UNEXPECTED; *aResult = (char *) nsMemory::Clone(start, (str - start) + 1); (*aResult)[str - start] = '\0'; // null-terminate NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); return NS_OK; } /* Skip forward to first ';' */ for (; *str && *str != ';' && *str != ','; ++str) ; if (*str) str++; /* Skip over following whitespace */ for (; *str && nsCRT::IsAsciiSpace(*str); ++str) ; // Some broken http servers just specify parameters // like 'filename' without sepcifying disposition // method. Rewind to the first non-white-space // character. if (!*str) str = start; // RFC2231 - The legitimate parm format can be: // A. title=ThisIsTitle // B. title*=us-ascii'en-us'This%20is%20wierd. // C. title*0*=us-ascii'en'This%20is%20wierd.%20We // title*1*=have%20to%20support%20this. // title*2="Else..." // D. title*0="Hey, what you think you are doing?" // title*1="There is no charset and lang info." PRInt32 paramLen = strlen(aParamName); while (*str) { const char *tokenStart = str; const char *tokenEnd = 0; const char *valueStart = str; const char *valueEnd = 0; NS_ASSERTION(!nsCRT::IsAsciiSpace(*str), "should be after whitespace."); // Skip forward to the end of this token. for (; *str && !nsCRT::IsAsciiSpace(*str) && *str != '=' && *str != ';'; str++) ; tokenEnd = str; // Skip over whitespace, '=', and whitespace while (nsCRT::IsAsciiSpace(*str)) ++str; if (*str == '=') ++str; while (nsCRT::IsAsciiSpace(*str)) ++str; if (*str != '"') { // The value is a token, not a quoted string. valueStart = str; for (valueEnd = str; *valueEnd && !nsCRT::IsAsciiSpace (*valueEnd) && *valueEnd != ';'; valueEnd++) ; str = valueEnd; } else { // The value is a quoted string. ++str; valueStart = str; for (valueEnd = str; *valueEnd; ++valueEnd) { if (*valueEnd == '\\') ++valueEnd; else if (*valueEnd == '"') break; } str = valueEnd + 1; } // See if this is the simplest case (case A above), // a 'single' line value with no charset and lang. // If so, copy it and return. if (tokenEnd - tokenStart == paramLen && !nsCRT::strncasecmp(tokenStart, aParamName, paramLen)) { // if the parameter spans across multiple lines we have to strip out the // line continuation -- jht 4/29/98 nsCAutoString tempStr(valueStart, valueEnd - valueStart); tempStr.StripChars("\r\n"); *aResult = ToNewCString(tempStr); NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); return NS_OK; } // case B, C, and D else if (tokenEnd - tokenStart > paramLen && !nsCRT::strncasecmp(tokenStart, aParamName, paramLen) && *(tokenStart + paramLen) == '*') { const char *cp = tokenStart + paramLen + 1; // 1st char pass '*' PRBool needUnescape = *(tokenEnd - 1) == '*'; // the 1st line of a multi-line parameter or a single line that needs // unescaping. ( title*0*= or title*= ) if ((*cp == '0' && needUnescape) || (tokenEnd - tokenStart == paramLen + 1)) { // look for single quotation mark(') const char *sQuote1 = PL_strchr(valueStart, 0x27); const char *sQuote2 = (char *) (sQuote1 ? PL_strchr(sQuote1 + 1, 0x27) : nsnull); // Two single quotation marks must be present even in // absence of charset and lang. if (!sQuote1 || !sQuote2) NS_WARNING("Mandatory two single quotes are missing in header parameter\n"); if (aCharset && sQuote1 > valueStart && sQuote1 < valueEnd) { *aCharset = (char *) nsMemory::Clone(valueStart, sQuote1 - valueStart + 1); if (*aCharset) *(*aCharset + (sQuote1 - valueStart)) = 0; } if (aLang && sQuote1 && sQuote2 && sQuote2 > sQuote1 + 1 && sQuote2 < valueEnd) { *aLang = (char *) nsMemory::Clone(sQuote1 + 1, sQuote2 - (sQuote1 + 1) + 1); if (*aLang) *(*aLang + (sQuote2 - (sQuote1 + 1))) = 0; } // Be generous and handle gracefully when required // single quotes are absent. if (sQuote1) { if(!sQuote2) sQuote2 = sQuote1; } else sQuote2 = valueStart - 1; if (sQuote2 && sQuote2 + 1 < valueEnd) { NS_ASSERTION(!*aResult, "This is the 1st line. result buffer should be null."); *aResult = (char *) nsMemory::Alloc(valueEnd - (sQuote2 + 1) + 1); if (*aResult) { memcpy(*aResult, sQuote2 + 1, valueEnd - (sQuote2 + 1)); *(*aResult + (valueEnd - (sQuote2 + 1))) = 0; if (needUnescape) { nsUnescape(*aResult); if (tokenEnd - tokenStart == paramLen + 1) // we're done; this is case B return NS_OK; } } } } // end of if-block : title*0*= or title*= // a line of multiline param with no need for unescaping : title*[0-9]= // or 2nd or later lines of a multiline param : title*[1-9]*= else if (nsCRT::IsAsciiDigit(PRUnichar(*cp))) { PRInt32 len = 0; if (*aResult) // 2nd or later lines of multiline parameter { len = strlen(*aResult); char *ns = (char *) nsMemory::Realloc(*aResult, len + (valueEnd - valueStart) + 1); if (!ns) { nsMemory::Free(*aResult); } *aResult = ns; } else if (*cp == '0') // must be; 1st line : title*0= { *aResult = (char *) nsMemory::Alloc(valueEnd - valueStart + 1); } // else {} something is really wrong; out of memory if (*aResult) { // append a partial value memcpy(*aResult + len, valueStart, valueEnd - valueStart); *(*aResult + len + (valueEnd - valueStart)) = 0; if (needUnescape) nsUnescape(*aResult + len); } else return NS_ERROR_OUT_OF_MEMORY; } // end of if-block : title*[0-9]= or title*[1-9]*= } // str now points after the end of the value. // skip over whitespace, ';', whitespace. while (nsCRT::IsAsciiSpace(*str)) ++str; if (*str == ';') ++str; while (nsCRT::IsAsciiSpace(*str)) ++str; } if (*aResult) return NS_OK; else return NS_ERROR_INVALID_ARG; // aParameter not found !! }
nsresult nsMIMEHeaderParamImpl::DoParameterInternal(const char *aHeaderValue, const char *aParamName, ParamDecoding aDecoding, char **aCharset, char **aLang, char **aResult) { if (!aHeaderValue || !*aHeaderValue || !aResult) return NS_ERROR_INVALID_ARG; *aResult = nsnull; if (aCharset) *aCharset = nsnull; if (aLang) *aLang = nsnull; nsCAutoString charset; bool acceptContinuations = (aDecoding != RFC_5987_DECODING); const char *str = aHeaderValue; // skip leading white space. for (; *str && nsCRT::IsAsciiSpace(*str); ++str) ; const char *start = str; // aParamName is empty. return the first (possibly) _unnamed_ 'parameter' // For instance, return 'inline' in the following case: // Content-Disposition: inline; filename=..... if (!aParamName || !*aParamName) { for (; *str && *str != ';' && !nsCRT::IsAsciiSpace(*str); ++str) ; if (str == start) return NS_ERROR_FIRST_HEADER_FIELD_COMPONENT_EMPTY; *aResult = (char *) nsMemory::Clone(start, (str - start) + 1); NS_ENSURE_TRUE(*aResult, NS_ERROR_OUT_OF_MEMORY); (*aResult)[str - start] = '\0'; // null-terminate return NS_OK; } /* Skip forward to first ';' */ for (; *str && *str != ';' && *str != ','; ++str) ; if (*str) str++; /* Skip over following whitespace */ for (; *str && nsCRT::IsAsciiSpace(*str); ++str) ; // Some broken http servers just specify parameters // like 'filename' without specifying disposition // method. Rewind to the first non-white-space // character. if (!*str) str = start; // RFC2231 - The legitimate parm format can be: // A. title=ThisIsTitle // B. title*=us-ascii'en-us'This%20is%20wierd. // C. title*0*=us-ascii'en'This%20is%20wierd.%20We // title*1*=have%20to%20support%20this. // title*2="Else..." // D. title*0="Hey, what you think you are doing?" // title*1="There is no charset and lang info." // RFC5987: only A and B // collect results for the different algorithms (plain filename, // RFC5987/2231-encoded filename, + continuations) separately and decide // which to use at the end char *caseAResult = NULL; char *caseBResult = NULL; char *caseCDResult = NULL; // collect continuation segments nsTArray<Continuation> segments; // our copies of the charset parameter, kept separately as they might // differ for the two formats nsDependentCSubstring charsetB, charsetCD; nsDependentCSubstring lang; PRInt32 paramLen = strlen(aParamName); while (*str) { // find name/value const char *nameStart = str; const char *nameEnd = NULL; const char *valueStart = str; const char *valueEnd = NULL; bool isQuotedString = false; NS_ASSERTION(!nsCRT::IsAsciiSpace(*str), "should be after whitespace."); // Skip forward to the end of this token. for (; *str && !nsCRT::IsAsciiSpace(*str) && *str != '=' && *str != ';'; str++) ; nameEnd = str; PRInt32 nameLen = nameEnd - nameStart; // Skip over whitespace, '=', and whitespace while (nsCRT::IsAsciiSpace(*str)) ++str; if (!*str) { break; } if (*str++ != '=') { // don't accept parameters without "=" goto increment_str; } while (nsCRT::IsAsciiSpace(*str)) ++str; if (*str != '"') { // The value is a token, not a quoted string. valueStart = str; for (valueEnd = str; *valueEnd && !nsCRT::IsAsciiSpace (*valueEnd) && *valueEnd != ';'; valueEnd++) ; str = valueEnd; } else { isQuotedString = true; ++str; valueStart = str; for (valueEnd = str; *valueEnd; ++valueEnd) { if (*valueEnd == '\\') ++valueEnd; else if (*valueEnd == '"') break; } str = valueEnd; // *valueEnd != null means that *valueEnd is quote character. if (*valueEnd) str++; } // See if this is the simplest case (case A above), // a 'single' line value with no charset and lang. // If so, copy it and return. if (nameLen == paramLen && !nsCRT::strncasecmp(nameStart, aParamName, paramLen)) { if (caseAResult) { // we already have one caseA result, ignore subsequent ones goto increment_str; } // if the parameter spans across multiple lines we have to strip out the // line continuation -- jht 4/29/98 nsCAutoString tempStr(valueStart, valueEnd - valueStart); tempStr.StripChars("\r\n"); char *res = ToNewCString(tempStr); NS_ENSURE_TRUE(res, NS_ERROR_OUT_OF_MEMORY); if (isQuotedString) RemoveQuotedStringEscapes(res); caseAResult = res; // keep going, we may find a RFC 2231/5987 encoded alternative } // case B, C, and D else if (nameLen > paramLen && !nsCRT::strncasecmp(nameStart, aParamName, paramLen) && *(nameStart + paramLen) == '*') { // 1st char past '*' const char *cp = nameStart + paramLen + 1; // if param name ends in "*" we need do to RFC5987 "ext-value" decoding bool needExtDecoding = *(nameEnd - 1) == '*'; bool caseB = nameLen == paramLen + 1; bool caseCStart = (*cp == '0') && needExtDecoding; // parse the segment number PRInt32 segmentNumber = -1; if (!caseB) { PRInt32 segLen = (nameEnd - cp) - (needExtDecoding ? 1 : 0); segmentNumber = parseSegmentNumber(cp, segLen); if (segmentNumber == -1) { acceptContinuations = false; goto increment_str; } } // CaseB and start of CaseC: requires charset and optional language // in quotes (quotes required even if lang is blank) if (caseB || (caseCStart && acceptContinuations)) { // look for single quotation mark(') const char *sQuote1 = PL_strchr(valueStart, 0x27); const char *sQuote2 = sQuote1 ? PL_strchr(sQuote1 + 1, 0x27) : nsnull; // Two single quotation marks must be present even in // absence of charset and lang. if (!sQuote1 || !sQuote2) { NS_WARNING("Mandatory two single quotes are missing in header parameter\n"); } const char *charsetStart = NULL; PRInt32 charsetLength = 0; const char *langStart = NULL; PRInt32 langLength = 0; const char *rawValStart = NULL; PRInt32 rawValLength = 0; if (sQuote2 && sQuote1) { // both delimiters present: charSet'lang'rawVal rawValStart = sQuote2 + 1; rawValLength = valueEnd - rawValStart; langStart = sQuote1 + 1; langLength = sQuote2 - langStart; charsetStart = valueStart; charsetLength = sQuote1 - charsetStart; } else if (sQuote1) { // one delimiter; assume charset'rawVal rawValStart = sQuote1 + 1; rawValLength = valueEnd - rawValStart; charsetStart = valueStart; charsetLength = sQuote1 - valueStart; } else { // no delimiter: just rawVal rawValStart = valueStart; rawValLength = valueEnd - valueStart; } if (langLength != 0) { lang.Assign(langStart, langLength); } // keep the charset for later if (caseB) { charsetB.Assign(charsetStart, charsetLength); } else { // if caseCorD charsetCD.Assign(charsetStart, charsetLength); } // non-empty value part if (rawValLength > 0) { if (!caseBResult && caseB) { // allocate buffer for the raw value char *tmpResult = (char *) nsMemory::Clone(rawValStart, rawValLength + 1); if (!tmpResult) { goto increment_str; } *(tmpResult + rawValLength) = 0; nsUnescape(tmpResult); caseBResult = tmpResult; } else { // caseC bool added = addContinuation(segments, 0, rawValStart, rawValLength, needExtDecoding, isQuotedString); if (!added) { // continuation not added, stop processing them acceptContinuations = false; } } } } // end of if-block : title*0*= or title*= // caseD: a line of multiline param with no need for unescaping : title*[0-9]= // or 2nd or later lines of a caseC param : title*[1-9]*= else if (acceptContinuations && segmentNumber != -1) { PRUint32 valueLength = valueEnd - valueStart; bool added = addContinuation(segments, segmentNumber, valueStart, valueLength, needExtDecoding, isQuotedString); if (!added) { // continuation not added, stop processing them acceptContinuations = false; } } // end of if-block : title*[0-9]= or title*[1-9]*= } // str now points after the end of the value. // skip over whitespace, ';', whitespace. increment_str: while (nsCRT::IsAsciiSpace(*str)) ++str; if (*str == ';') { ++str; } else { // stop processing the header field; either we are done or the // separator was missing break; } while (nsCRT::IsAsciiSpace(*str)) ++str; } caseCDResult = combineContinuations(segments); if (caseBResult && !charsetB.IsEmpty()) { // check that the 2231/5987 result decodes properly given the // specified character set if (!IsValidOctetSequenceForCharset(charsetB, caseBResult)) caseBResult = NULL; } if (caseCDResult && !charsetCD.IsEmpty()) { // check that the 2231/5987 result decodes properly given the // specified character set if (!IsValidOctetSequenceForCharset(charsetCD, caseCDResult)) caseCDResult = NULL; } if (caseBResult) { // prefer simple 5987 format over 2231 with continuations *aResult = caseBResult; caseBResult = NULL; charset.Assign(charsetB); } else if (caseCDResult) { // prefer 2231/5987 with or without continuations over plain format *aResult = caseCDResult; caseCDResult = NULL; charset.Assign(charsetCD); } else if (caseAResult) { *aResult = caseAResult; caseAResult = NULL; } // free unused stuff nsMemory::Free(caseAResult); nsMemory::Free(caseBResult); nsMemory::Free(caseCDResult); // if we have a result if (*aResult) { // then return charset and lang as well if (aLang && !lang.IsEmpty()) { PRUint32 len = lang.Length(); *aLang = (char *) nsMemory::Clone(lang.BeginReading(), len + 1); if (*aLang) { *(*aLang + len) = 0; } } if (aCharset && !charset.IsEmpty()) { PRUint32 len = charset.Length(); *aCharset = (char *) nsMemory::Clone(charset.BeginReading(), len + 1); if (*aCharset) { *(*aCharset + len) = 0; } } } return *aResult ? NS_OK : NS_ERROR_INVALID_ARG; }