bool getConfigDoubleValue(char * buf,char *key,double &val)
{
	int bufLen = (int)strlen(buf);
	int keyLen = (int)strlen(key);
	int start = findStr(buf,key,bufLen,keyLen);
	int valueStart = start+keyLen;
	int end = findStr(buf,"\n",bufLen,1,valueStart);
	if(start == -1 || end == -1)
	{
		return false;
	}
	char str[500] = {0};
	int i,j;
	if(end - valueStart >= 500)
	{
		return false;
	}
	for(i = valueStart,j = 0; i < end; i++,j++)
	{
		str[j] = buf[i];
	}
	str[end] = 0;
	val = atof(str);
	return true;
}
示例#2
0
static void doWork(Crew *crew, Work *work)
{
	int status;
	struct stat filestat;
	struct dirent *dirbuf;
	status = lstat(work->path, &filestat);
	if (status != 0)
		return;

	if (S_ISDIR(filestat.st_mode)) {
		DIR *pDir = opendir(work->path);
		if (pDir == NULL) {
			return;	
		}
		while ((dirbuf = readdir(pDir)) != NULL) {
			if (strcmp(dirbuf->d_name, ".") == 0 || strcmp(dirbuf->d_name, "..") == 0) {
				continue;
			}
			status = pthread_mutex_lock(&crew->mutex);
			if (status != 0) 
				return;
			addWork(crew, work->path, dirbuf->d_name, work->string);
			status = pthread_cond_signal(&crew->go);
			if (status != 0)
				return;
			status = pthread_mutex_unlock(&crew->mutex);
			if (status != 0) 
				return;
		}
	} else if (S_ISREG(filestat.st_mode)) {
		findStr(work);
	}
}
bool getConfigMapTable(char * buf,char *key,int *dstTable,int dstLen)
{
	int bufLen = (int)strlen(buf);
	int keyLen = (int)strlen(key);
	int start = findStr(buf,key,bufLen,keyLen);
	int valueStart = start+keyLen;
	int end = findStr(buf,"\n",bufLen,1,valueStart);
	if(start == -1 || end == -1)
	{
		return false;
	}
	char str[500];
	if(end - valueStart >= 500)
	{
		return false;
	}
	int i,j;
	int idx = 0;
	int x = 0;
	for(i = valueStart,j = 0; i <= end; i++,j++)
	{
		if(buf[i] == ',' || buf[i] == '\n')
		{
			str[x] = 0;
			x = -1;
			if(idx >= dstLen)
			{
				return false;
			}
			dstTable[idx++] = atoi(str);
		}
		else
		{
			str[x] = buf[i];
		}
		x++;
	}
	return true;
}
bool getConfigStrValue(char * buf,char *key,char *dstStr,int dstLen)
{
	int bufLen = (int)strlen(buf);
	int keyLen = (int)strlen(key);
	int start = findStr(buf,key,bufLen,keyLen);
	int valueStart = start+keyLen;
	int end = findStr(buf,"\n",bufLen,1,valueStart);
	if(start == -1 || end == -1)
	{
		return false;
	}
	if(end - valueStart >= dstLen)
	{
		return false;
	}
	int i,j;
	for(i = valueStart,j = 0; i < end; i++,j++)
	{
		dstStr[j] = buf[i];
	}
	dstStr[end] = 0;
	return true;
}
示例#5
0
void IniFile::parseText(BufInputStream& txtFile)
{
    //txtFile.seek(0, skBegin);
    clearList();
    const char notesFlag = ';';
    String strLine;
    while (txtFile.readLine(strLine))
    {
        trimTo(strLine);
        String& strTmp=strLine;
        long strTmp_size=(long)strTmp.size();
        //Notes
        if ((strTmp_size > 0) && (notesFlag != strTmp[0]))		
        {
            //Section
            if (strTmp_size >= 2)
            {
                if ((sectionStart == strTmp[0]) && (sectionEnd == strTmp[strTmp_size - 1]))
                {
                    String strSection;
                    trim(strTmp.c_str()+1,strTmp_size-2,strSection);
                    m_sctList.push_back(Section(strSection));
                }
                else
                {
                    long nIdxSpace = findStr(strTmp, valSpace);
                    if (nIdxSpace >= 0) {
                        String strKey;
                        trim(strTmp.c_str(),nIdxSpace,strKey);
                        
                        String strVal;
                        if ((nIdxSpace + 1) < strTmp_size) 
                            trim(strTmp.c_str()+nIdxSpace + 1,strTmp_size - nIdxSpace - 1,strVal);
                        getBackSection()->list.push_back(IniValue(strKey, strVal));
                    }
                    //else getBackSection()->list.push_back(IniValue(strLine));					
                }				
            }
            //else getBackSection()->list.push_back(IniValue(strLine));
        }
        else 
        {
            getBackSection()->list.push_back(IniValue(strLine));
        }
    }	
}
示例#6
0
SearchData FindInFilesDialog::DoGetSearchData()
{
    SearchData data;
    wxString findStr(m_data.GetFindString());
    if(m_findString->GetValue().IsEmpty() == false) {
        findStr = m_findString->GetValue();
    }

    data.SetFindString(findStr);

    m_data.SetFlags(GetSearchFlags());
    size_t flags = m_data.GetFlags();

    // If the 'Skip comments' is ON, remove the
    // 'colour comments' flag
    if(flags & wxFRD_SKIP_COMMENTS) {
        flags &= ~wxFRD_COLOUR_COMMENTS;
    }

    data.SetMatchCase((flags & wxFRD_MATCHCASE) != 0);
    data.SetMatchWholeWord((flags & wxFRD_MATCHWHOLEWORD) != 0);
    data.SetRegularExpression((flags & wxFRD_REGULAREXPRESSION) != 0);
    data.SetDisplayScope((flags & wxFRD_DISPLAYSCOPE) != 0);
    data.SetEncoding(m_choiceEncoding->GetStringSelection());
    data.SetSkipComments(flags & wxFRD_SKIP_COMMENTS);
    data.SetSkipStrings(flags & wxFRD_SKIP_STRINGS);
    data.SetColourComments(flags & wxFRD_COLOUR_COMMENTS);
    wxArrayString rootDirs;
    for(size_t i = 0; i < m_listPaths->GetCount(); ++i) {
        rootDirs.push_back(m_listPaths->GetString(i));
    }
    if(rootDirs.IsEmpty()) {
        wxString dir = m_dirPicker->GetPath();
        if(dir.IsEmpty() == false) {
            rootDirs.push_back(dir);
        }
    }
    data.SetRootDirs(rootDirs);

    wxArrayString files;
    for(size_t i = 0; i < rootDirs.GetCount(); ++i) {
        const wxString& rootDir = rootDirs.Item(i);
        // Check both translations and otherwise: the history may contain either
        if((rootDir == wxGetTranslation(SEARCH_IN_WORKSPACE)) || (rootDir == SEARCH_IN_WORKSPACE)) {
            ManagerST::Get()->GetWorkspaceFiles(files);

        } else if((rootDir == wxGetTranslation(SEARCH_IN_PROJECT)) || (rootDir == SEARCH_IN_PROJECT)) {
            ManagerST::Get()->GetActiveProjectFiles(files);

        } else if((rootDir == wxGetTranslation(SEARCH_IN_CURR_FILE_PROJECT)) ||
                  (rootDir == SEARCH_IN_CURR_FILE_PROJECT)) {
            ManagerST::Get()->GetActiveFileProjectFiles(files);

        } else if((rootDir == wxGetTranslation(SEARCH_IN_CURRENT_FILE)) || (rootDir == SEARCH_IN_CURRENT_FILE)) {
            LEditor* editor = clMainFrame::Get()->GetMainBook()->GetActiveEditor();
            if(editor) {
                files.Add(editor->GetFileName().GetFullPath());
            }
        } else if((rootDir == wxGetTranslation(SEARCH_IN_OPEN_FILES)) || (rootDir == SEARCH_IN_OPEN_FILES)) {
            std::vector<LEditor*> editors;
            clMainFrame::Get()->GetMainBook()->GetAllEditors(editors, MainBook::kGetAll_IncludeDetached);

            for(size_t n = 0; n < editors.size(); ++n) {
                LEditor* editor = dynamic_cast<LEditor*>(*(editors.begin() + n));
                if(editor) {
                    files.Add(editor->GetFileName().GetFullPath());
                }
            }
        }
    }

    data.SetFiles(files);
    data.UseNewTab(m_checkBoxSeparateTab->IsChecked());
    data.SetExtensions(m_fileTypes->GetValue());
    return data;
}
SearchData FindInFilesDialog::DoGetSearchData()
{
    SearchData data;
    wxString findStr(m_data.GetFindString());
    if(!m_findString->GetValue().IsEmpty()) {
        findStr = m_findString->GetValue();
    }

    data.SetFindString(findStr);
    data.SetReplaceWith(m_replaceString->GetValue());

    m_data.SetFlags(GetSearchFlags());
    size_t flags = m_data.GetFlags();

    // If the 'Skip comments' is ON, remove the
    // 'colour comments' flag
    if(flags & wxFRD_SKIP_COMMENTS) {
        flags &= ~wxFRD_COLOUR_COMMENTS;
    }

    data.SetMatchCase((flags & wxFRD_MATCHCASE) != 0);
    data.SetMatchWholeWord((flags & wxFRD_MATCHWHOLEWORD) != 0);
    data.SetRegularExpression((flags & wxFRD_REGULAREXPRESSION) != 0);
    data.SetDisplayScope((flags & wxFRD_DISPLAYSCOPE) != 0);
    data.SetEncoding(m_choiceEncoding->GetStringSelection());
    data.SetSkipComments(flags & wxFRD_SKIP_COMMENTS);
    data.SetSkipStrings(flags & wxFRD_SKIP_STRINGS);
    data.SetColourComments(flags & wxFRD_COLOUR_COMMENTS);
    data.SetEnablePipeSupport(flags & wxFRD_ENABLE_PIPE_SUPPORT);
    wxArrayString searchWhere = m_listPaths->GetStrings();
    wxArrayString files;
    wxArrayString rootDirs;

    for(size_t i = 0; i < searchWhere.GetCount(); ++i) {
        const wxString& rootDir = searchWhere.Item(i);
        // Check both translations and otherwise: the history may contain either
        if((rootDir == wxGetTranslation(SEARCH_IN_WORKSPACE)) || (rootDir == SEARCH_IN_WORKSPACE)) {
            if(!clWorkspaceManager::Get().IsWorkspaceOpened()) continue;
            clWorkspaceManager::Get().GetWorkspace()->GetWorkspaceFiles(files);

        } else if((rootDir == wxGetTranslation(SEARCH_IN_PROJECT)) || (rootDir == SEARCH_IN_PROJECT)) {
            if(!clWorkspaceManager::Get().IsWorkspaceOpened()) continue;
            if(clWorkspaceManager::Get().GetWorkspace()->IsProjectSupported()) {
                // get the active project files
                clWorkspaceManager::Get().GetWorkspace()->GetProjectFiles("", files);
            } else {
                // search the entire workspace
                clWorkspaceManager::Get().GetWorkspace()->GetWorkspaceFiles(files);
            }

        } else if((rootDir == wxGetTranslation(SEARCH_IN_CURR_FILE_PROJECT)) ||
                  (rootDir == SEARCH_IN_CURR_FILE_PROJECT)) {

            if(!clWorkspaceManager::Get().IsWorkspaceOpened()) continue;
            IEditor* editor = clGetManager()->GetActiveEditor();
            if(!editor) continue;

            if(clWorkspaceManager::Get().GetWorkspace()->IsProjectSupported()) {
                wxString projectName =
                    clWorkspaceManager::Get().GetWorkspace()->GetProjectFromFile(editor->GetFileName());
                clWorkspaceManager::Get().GetWorkspace()->GetProjectFiles(projectName, files);
            } else {
                // search the entire workspace
                clWorkspaceManager::Get().GetWorkspace()->GetWorkspaceFiles(files);
            }

        } else if((rootDir == wxGetTranslation(SEARCH_IN_CURRENT_FILE)) || (rootDir == SEARCH_IN_CURRENT_FILE)) {
            LEditor* editor = clMainFrame::Get()->GetMainBook()->GetActiveEditor();
            if(editor) {
                files.Add(editor->GetFileName().GetFullPath());
            }
        } else if((rootDir == wxGetTranslation(SEARCH_IN_OPEN_FILES)) || (rootDir == SEARCH_IN_OPEN_FILES)) {
            std::vector<LEditor*> editors;
            clMainFrame::Get()->GetMainBook()->GetAllEditors(editors, MainBook::kGetAll_IncludeDetached);

            for(size_t n = 0; n < editors.size(); ++n) {
                LEditor* editor = dynamic_cast<LEditor*>(*(editors.begin() + n));
                if(editor) {
                    files.Add(editor->GetFileName().GetFullPath());
                }
            }
        } else if(wxFileName::DirExists(searchWhere.Item(i))) {
            rootDirs.Add(searchWhere.Item(i));
        }
    }

    // Remove duplicates
    wxStringSet_t filesSet;
    wxArrayString uniqueFiles;
    std::for_each(files.begin(), files.end(), [&](const wxString& file) {
        if(filesSet.count(file) == 0) {
            filesSet.insert(file);
            uniqueFiles.Add(file);
        }
    });

    files.swap(uniqueFiles);

    data.SetFiles(files);       // list of files
    data.SetRootDirs(rootDirs); // folders
    data.UseNewTab(false);
    data.SetExtensions(m_fileTypes->GetValue());
    return data;
}
// Smooth Streaming On Demand Publisher
int
smoothstreamingSSP(con_t *con, const char *uriData, int uriLen, \
		   const ssp_config_t *ssp_cfg, \
		   off_t contentLen, const char *dataBuf, int bufLen)
{
    const char *uri;
    char *p_qpos, *p_fpos, *p_cmpos;
    char *manifest_uri, *media_uri;
    const char *video_qparam_name, *audio_qparam_name;
    uint8_t track_type, mfro[16];
    uint16_t pos=0, track_id;
    uint32_t manifest_uri_size=0;
    uint32_t bit_rate;
    uint64_t time_offset=0;
    uint32_t box_size;

    size_t mfra_off=0, moof_size=0, moof_offset=0, moof_time=0;
    xml_read_ctx_t *ism;
    ism_bitrate_map_t *map;
    ismv_parser_ctx_t *ctx;

    int remap_len=0, rv, err;

    const char *tmpData;
    int tmpLen=0, tmpCnt=0;
    unsigned int tmpAttrs=0;

    http_cb_t *phttp = &con->http;

    // Obtain the relative URL length stripped of all query params
    if ( (remap_len = findStr(uriData, "?", uriLen)) == -1 ) {
	remap_len = uriLen;
    }

    if ( ssp_cfg->smoothstream_pub.quality_tag == NULL || \
	 ssp_cfg->smoothstream_pub.fragment_tag == NULL ) {
	DBG_LOG(ERROR, MOD_SSP, "Required Quality/Frag tags unspecified in CLI, exiting...");
        return -NKN_SSP_CLI_PARAM_UNSPECIFIED;
    }

    // If request is for client manifest (.ismc is requested as .ism/Manifest)
    // Rebase URI and return
    p_cmpos = strcasestr(uriData, ".ism/Manifest");
    if ( p_cmpos != NULL ) {
	manifest_uri_size = p_cmpos - uriData + strlen(".ismc") + SSP_MAX_EXTENSION_SZ;
	manifest_uri = (char *)alloca(manifest_uri_size);
	memset(manifest_uri, 0, manifest_uri_size);
	manifest_uri[0]='\0';
	strncat(manifest_uri, uriData, (p_cmpos-uriData) );
	strncat(manifest_uri, ".ismc", strlen(".ismc"));

	add_known_header(&phttp->hdr, MIME_HDR_X_NKN_DECODED_URI, manifest_uri, strlen(manifest_uri));
	add_known_header(&phttp->hdr, MIME_HDR_X_NKN_URI, manifest_uri, strlen(manifest_uri));

	phttp->p_ssp_cb->ssp_streamtype = NKN_SSP_SMOOTHSTREAM_STREAMTYPE_MANIFEST; // text/xml
	DBG_LOG(MSG, MOD_SSP, "SmoothStream Pub: Client manifest file request %s", manifest_uri);

	rv = SSP_SEND_DATA_OTW;
	goto exit;
    }

    /*************************************************************
     * State Flow for Smooth Stream Publishing
     * State 0:
     *		Remap URI to fetch .ISM Server Manifest, SEND_DATA_BACK_TO_SSP
     * State 10:
     *		Parse the XML .ism buffer, extract track id, quality, source name, etc
     *		Remap URI to source name, SEND_DATA_BACK_TO_SSP
     * State 20:
     * 		Read the content length, Trigger a byte range fetch from EOF-16
     *		This is to get the MFRO box (Assuming that it is the last box)
     * 		SEND_DATA_BACK_TO_SSP
     * State 30:
     * 		Parse the MFRO box, find the MFRA offset.
     *		Trigger a byte range fetch to MFRA
     *		SEND_DATA_BACK_TO_SSP
     * State 40:
     *		Allocate buffer for MFRA box, loop and copy the data in chunked fashion
     *		Return code will be SSP_WAIT_FOR_DATA till all chunked data is read.
     *		Fall through to State 50
     *		Parse the MFRA box using the time offset provided
     *		Determine the moof offset and size.
     * State 50:
     *		To determine the size of the fragment first do a internal 4 byte fetch
     *		to find the box size for the moof header, then go to next state
     * State 60:
     *		Again perform a 4-byte fetch to find the size of the mdat box. The sum
     * 		of both the sizes, gives the moof length. Now set the actual byte range
     * 		fetch and send over the wire SEND_DATA_OTW
     */

    switch(con->ssp.seek_state) {

	case 0:

            // Reset all previous stateful variables to 0
	    // (Helpful when GET requests are pipelined in the same keep alive conn)
            con->ssp.ss_seek_offset = 0;
	    con->ssp.ss_track_type = 0;
	    con->ssp.ss_bit_rate = 0;
	    con->ssp.ssp_br_offset = 0;
	    con->ssp.ssp_br_length = 0;

            CLEAR_HTTP_FLAG(phttp, HRF_BYTE_RANGE);
	    CLEAR_HTTP_FLAG(phttp, HRF_SSP_NO_AM_HITS);
            con->ssp.header_size = 0;
            if ( con->ssp.header ) {
                free(con->ssp.header);
                con->ssp.header = NULL;
            }
            con->ssp.ssp_partial_content_len = 0;
	    con->ssp.ssp_streamtype = 0;

	    // Remap .ism file uri and request to send to ssp
	    p_qpos = strstr(uriData, ssp_cfg->smoothstream_pub.quality_tag);
	    p_fpos = strstr(uriData, ssp_cfg->smoothstream_pub.fragment_tag);

	    if (p_qpos && p_fpos) { // Process only if uri is a valid ss uri
		// Extract/Create the server manifest uri (*.ism)
		manifest_uri_size = p_qpos - uriData;
		manifest_uri = (char *)alloca(manifest_uri_size + SSP_MAX_EXTENSION_SZ);
		memset(manifest_uri, 0, manifest_uri_size + SSP_MAX_EXTENSION_SZ);
		manifest_uri[0] = '\0';
		strncat(manifest_uri, uriData, manifest_uri_size-1);

#if 0
		parse_smoothstream_uri(uriData, ssp_cfg->smoothstream_pub.quality_tag, \
		    	       ssp_cfg->smoothstream_pub.fragment_tag,	\
		    	       "video", "audio",			\
		    	       &track_type, &bit_rate, &time_offset);
		con->ssp.ss_track_type = track_type;
		con->ssp.ss_bit_rate = bit_rate;
		con->ssp.ss_seek_offset = time_offset;

		snprintf(con->ssp.ss_orig_uri, uriLen, "%s", uriData);

		if(time_offset > 0) //BZ 6541
		    SET_HTTP_FLAG(phttp, HRF_SSP_NO_AM_HITS);

		DBG_LOG(MSG, MOD_SSP, "SmoothStream Pub (State: 0):"
			"Parsed Quality: %d, Time: %ld", con->ssp.ss_bit_rate, con->ssp.ss_seek_offset);
#endif
		DBG_LOG(MSG, MOD_SSP, "SmoothStream Pub (State: 0): Fetch .ism file %s", manifest_uri);

		add_known_header(&phttp->hdr, MIME_HDR_X_NKN_REMAPPED_URI, manifest_uri, strlen(manifest_uri));
		add_known_header(&phttp->hdr, MIME_HDR_X_NKN_SEEK_URI, manifest_uri, strlen(manifest_uri));

		con->ssp.seek_state = 10;
		rv = SSP_SEND_DATA_BACK;
		goto exit;
	    } else { // just allow to pass through
		DBG_LOG(MSG, MOD_SSP, "SmoothStream Pub (State: 0): Original URI not SS compliant: %s", uriData);

		rv = SSP_SEND_DATA_OTW;
		goto exit;
	    }

	    break;

	case 10:
	    // Obtain .ism file, parse the XML context and extract track/src data
	    if (contentLen == OM_STAT_SIG_TOT_CONTENT_LEN || contentLen == 0) { // File not found
		DBG_LOG(WARNING, MOD_SSP,
			"SmoothStream Pub (State: 10): Server Manifest not found. Cannot proceed");

		rv = -NKN_SSP_SS_SVR_MANIFEST_ISM_NOT_FOUND;
		goto exit;
	    }

	    // Manifest found, initiate xml parser (chunked fetch for .ISM files not supported)
	    if (dataBuf != NULL && contentLen <= bufLen) {
		//const char *orig_uri = uriData;//con->ssp.ss_orig_uri; [BZ 10387]

		/* delete the known MIME headers set in state 0 */
		delete_known_header(&phttp->hdr, MIME_HDR_X_NKN_SEEK_URI);
		delete_known_header(&phttp->hdr, MIME_HDR_X_NKN_REMAPPED_URI);

		// Obtain the original restful URL [BZ 10387]
		if (get_known_header(&phttp->hdr, MIME_HDR_X_NKN_DECODED_URI, &tmpData, &tmpLen, &tmpAttrs, &tmpCnt)) {
		    if (get_known_header(&phttp->hdr , MIME_HDR_X_NKN_URI, &tmpData, &tmpLen, &tmpAttrs, &tmpCnt)) {
			DBG_LOG(WARNING, MOD_SSP,
				"SmoothStream Pub (State: 10): Failed to extract url from NKN_URI");
			return -NKN_SSP_BAD_URL;
		    }
		}

		/* read the server manifest ism file into an XML context */
		ism = init_xml_read_ctx( (uint8_t *)dataBuf, bufLen);

		/* read the [trackid, bitrate] map from the ism file context */
		map = ism_read_bitrate_map(ism);

		/* read the bitrate from the uri, this is necessary to
		 * query the "trackName" attribute from the ism bitrate
		 * map
		*/
		rv = smoothstream_uri_get_ql(tmpData,
					ssp_cfg->smoothstream_pub.quality_tag,
					&bit_rate);
		if (rv!=0){
		    DBG_LOG(WARNING, MOD_SSP,
                            "SmoothStream Pub (State: 10): Tags positions not found. Exiting");
                    rv = SSP_SEND_DATA_OTW;
                    goto exit;
		}

		/* retrieve the query param name for the A/V track
		 * for the given bitrate. if the "trackName" attribute
		 * is not present the we fallback to defaults
		 */
		err = ism_get_video_qparam_name(map, bit_rate,
						&video_qparam_name);
		if (err == ISM_USE_DEF_QPARAM) {
		    video_qparam_name =			\
			smoothstream_def_av_qparam_name[0];
		}
		err = ism_get_audio_qparam_name(map, bit_rate,
						&audio_qparam_name);
		if (err == ISM_USE_DEF_QPARAM) {
		    audio_qparam_name =			\
			smoothstream_def_av_qparam_name[1];
		}

		/* now parse with the audio and video query param tag
		 * parsed from the ism bitrate map
		 */
		rv = parse_smoothstream_uri(tmpData, ssp_cfg->smoothstream_pub.quality_tag, \
				       ssp_cfg->smoothstream_pub.fragment_tag, \
				       video_qparam_name, audio_qparam_name, \
				       &track_type, &bit_rate,
				       &time_offset);
		if (rv!=0){
                    DBG_LOG(WARNING, MOD_SSP,
                            "SmoothStream Pub (State: 10): Tags positions not found. Exiting");
                    rv = SSP_SEND_DATA_OTW;
                    goto exit;
                }

		con->ssp.ss_track_type = track_type;
		con->ssp.ss_bit_rate = bit_rate;
		con->ssp.ss_seek_offset = time_offset;
		if(time_offset > 0) //BZ 6541
		    SET_HTTP_FLAG(phttp, HRF_SSP_NO_AM_HITS);

		/* find the trackid for a given track type and bitrate */
		track_id = ism_get_track_id(map, con->ssp.ss_bit_rate, con->ssp.ss_track_type);
		if (track_id == 0) {
		    DBG_LOG(WARNING, MOD_SSP,
			    "SmoothStream Pub (State: 10):"
			    "Unable to find a track corresponding to bit rate %d kbps. Close conn ",
			    con->ssp.ss_bit_rate);
		    rv = -NKN_SSP_SS_TRACK_NOT_FOUND;
		    goto exit;
		}

		/* Use track id to find the source file name */
		uri = ism_get_video_name(map, con->ssp.ss_track_type,
					 track_id,
					 con->ssp.ss_bit_rate, NULL,
					 NULL, 0);

		if (con->ssp.ss_track_type == 0) {
		    phttp->p_ssp_cb->ssp_streamtype = NKN_SSP_SMOOTHSTREAM_STREAMTYPE_VIDEO; //video/mp4
		} else if (con->ssp.ss_track_type == 1) {
		    phttp->p_ssp_cb->ssp_streamtype = NKN_SSP_SMOOTHSTREAM_STREAMTYPE_AUDIO; //audio/mp4
		}

		con->ssp.ss_track_id = track_id;
		//con->ssp.ss_seek_offset = time_offset;

		// Create the source file URI for the .ISMV or .ISMA
		// file
		p_qpos = strstr(tmpData, ssp_cfg->smoothstream_pub.quality_tag);
		p_fpos = strstr(tmpData, ssp_cfg->smoothstream_pub.fragment_tag);

		if (p_qpos == NULL || p_fpos == NULL) { // [BZ 10387]
		    DBG_LOG(WARNING, MOD_SSP,
			    "SmoothStream Pub (State: 10): Tags positions not found. Exiting");
		    rv = SSP_SEND_DATA_OTW;
		    goto exit;
		}

		// Extract/Create the server manifest uri (*.ism)
		manifest_uri_size = p_qpos - tmpData;
		if (manifest_uri_size > strlen(tmpData)) { // [BZ 10387]
		    DBG_LOG(WARNING, MOD_SSP,
                            "SmoothStream Pub (State: 10): uri size gone out of bounds. Exiting");
                    rv = SSP_SEND_DATA_OTW;
                    goto exit;
		}

		manifest_uri = (char *)alloca(manifest_uri_size + SSP_MAX_EXTENSION_SZ);
		memset(manifest_uri, 0,	manifest_uri_size + SSP_MAX_EXTENSION_SZ);
		manifest_uri[0] = '\0';
		strncat(manifest_uri, tmpData, manifest_uri_size-1);

		pos = find_base_uri_endpos(manifest_uri, ssp_cfg->smoothstream_pub.quality_tag);
		media_uri = (char *)alloca(pos + strlen(uri) + SSP_MAX_EXTENSION_SZ);
		memset(media_uri, 0, pos + strlen(uri) + SSP_MAX_EXTENSION_SZ);
		media_uri[0] = '\0';
		strncat(media_uri, manifest_uri, pos);
		strncat(media_uri, uri, strlen(uri));

		// Uri for the media asset (Could be an ISMV or ISMA or a packaged ISMV file)
		add_known_header(&phttp->hdr, MIME_HDR_X_NKN_DECODED_URI, media_uri, strlen(media_uri));
		add_known_header(&phttp->hdr, MIME_HDR_X_NKN_URI, media_uri, strlen(media_uri));
		SET_HTTP_FLAG(phttp, HRF_SSP_NO_AM_HITS); // BZ 6541
		DBG_LOG(MSG, MOD_SSP, "SmoothStream Pub (State 10):"
			"Got .ism file, fetching .ismv file %s [QL: %d, Time: %ld]",
			media_uri, con->ssp.ss_bit_rate, con->ssp.ss_seek_offset);

		ism_cleanup_map(map);
		xml_cleanup_ctx(ism);

		con->ssp.seek_state = 20;
		rv = SSP_SEND_DATA_BACK;
		goto exit;
	    } else {
		DBG_LOG(WARNING, MOD_SSP,
			"SmoothStream Pub (State: 10): NULL dataBuf returned for Server Manifest");
		rv = -NKN_SSP_SS_NULL_BUF_INT_FETCH;
		goto exit;
	    }

	    break;

	case 20:
	    // Find the content length of the media file, set a byte range request for mfro box

	    if (contentLen == OM_STAT_SIG_TOT_CONTENT_LEN || contentLen == 0) { // File not found
                DBG_LOG(WARNING, MOD_SSP,
			"SmoothStream Pub (State: 20): .ISMV Media file not found. Cannot proceed");

                rv = -NKN_SSP_SS_ISMV_ISMA_NOT_FOUND;
                goto exit;
            }

	    if (dataBuf != NULL) {
		con->ssp.ssp_content_length = contentLen;

		// Fixed offset from EOF
		phttp->brstart = contentLen - 16;
		phttp->brstop = 0;
		SET_HTTP_FLAG(phttp, HRF_BYTE_RANGE);
		DBG_LOG(MSG, MOD_SSP,
			"SmoothStream Pub (State 20): Requesting mfro box (Off/Size:  %ld/%ld) [Time: %ld]",
			phttp->brstart, con->ssp.ssp_content_length, con->ssp.ss_seek_offset);

		con->ssp.seek_state = 30;
		rv = SSP_SEND_DATA_BACK;
		goto exit;
	    } else {
		DBG_LOG(WARNING, MOD_SSP,
			"SmoothStream Pub (State: 20): NULL dataBuf returned for ISMV media file");

                rv = -NKN_SSP_SS_NULL_BUF_INT_FETCH;
                goto exit;
	    }

	    break;

	case 30:
	    /* For fragmented ISMV files, the mfro box is usually the last box
	     * in the file and is of fixed size.
	     * The mfro box gives the offset in the file for the mfra box.
	     * The mfra box in turn has information about the timestamp & offset of each moof fragment
	     */

            if (contentLen == OM_STAT_SIG_TOT_CONTENT_LEN || contentLen == 0) { // File not found
                DBG_LOG(WARNING, MOD_SSP, "SmoothStream Pub (State: 30): Byte range fetch for MFRO failed. Cannot proceed");

                rv = -NKN_SSP_SS_ISMV_ISMA_NOT_FOUND;
                goto exit;
            }

	    if (dataBuf != NULL) {
		memset(mfro, 0, 16);
		memcpy(mfro, dataBuf, 16);

		/* read the mfra offset from the mfro box */
		mfra_off = con->ssp.ssp_content_length - mp4_get_mfra_offset(mfro, 16);
		if(mfra_off == con->ssp.ssp_content_length) {
		    DBG_LOG(WARNING, MOD_SSP, "SmoothStream Pub (State: 30): MFRO box offset read failed");
		    rv = -NKN_SSP_SS_MFRO_OFF_FAIL;
		    goto exit;
		}

		phttp->brstart = mfra_off;
		phttp->brstop = 0;
		SET_HTTP_FLAG(phttp, HRF_BYTE_RANGE);
		con->ssp.header_size = con->ssp.ssp_content_length - mfra_off; // Size of MFRA box till the end
                DBG_LOG(MSG, MOD_SSP,
			"SmoothStream Pub (State: 30): Requesting the MFRA box (Off/Size:  %ld/%ld) [Time: %ld]",
			phttp->brstart, con->ssp.ssp_content_length, con->ssp.ss_seek_offset);

                con->ssp.seek_state = 40;
                rv = SSP_SEND_DATA_BACK;
		goto exit;
	    } else {
		DBG_LOG(WARNING, MOD_SSP, "SmoothStream Pub (State: 30): NULL dataBuf returned for MFRO offset");

                rv = -NKN_SSP_SS_NULL_BUF_INT_FETCH;
                goto exit;
	    }

	    break;

	case 40:
	    // Buffered loopback read to copy the entire MFRA box
	    if (contentLen == OM_STAT_SIG_TOT_CONTENT_LEN || contentLen == 0) { // File not found
                DBG_LOG(WARNING, MOD_SSP, "SmoothStream Pub (State: 40): Byte range fetch for MFRA failed");
                rv = -NKN_SSP_SS_ISMV_ISMA_NOT_FOUND;
                goto exit;
            }

	    if ( !con->ssp.header ) { // Buffer for MFRA box
		con->ssp.header = (uint8_t *)nkn_calloc_type(con->ssp.header_size,
							     sizeof(char), mod_ssp_smoothstream_pub_t);
		if (con->ssp.header == NULL) {
		    DBG_LOG(WARNING, MOD_SSP,
			    "SmoothStream Pub (State: 40): Failed to allocate space for copy MFRA box");
		    CLEAR_HTTP_FLAG(phttp, HRF_BYTE_RANGE);
		    rv = -NKN_SSP_SS_MEM_ALLOC_HDR_FAIL; // error case
		    goto exit;
		}
		con->ssp.ssp_partial_content_len = 0;
	    }

	    if (dataBuf != NULL) {
		memcpy(con->ssp.header + con->ssp.ssp_partial_content_len, dataBuf, bufLen);
		con->ssp.ssp_partial_content_len += bufLen;

		if (con->ssp.ssp_partial_content_len < con->ssp.header_size) {
		    DBG_LOG(MSG, MOD_SSP,
			    "SmoothStream Pub (State: 40): Chunked read for MFRA box, read %d of %ld [Time: %ld]",
			    con->ssp.ssp_partial_content_len, con->ssp.header_size, con->ssp.ss_seek_offset);
		    rv = SSP_WAIT_FOR_DATA;
		    goto exit;
		}
	    }

	    // Parse the populated MFRA box to glean the offset and length for the MOOF fragment
	    /* initialize the ismv context */
	    ctx = mp4_init_ismv_parser_ctx(con->ssp.header, con->ssp.header_size, NULL);

	    /* seek to a timestamp in a track id, returns the correct moof
	     * offset and its length; track id determined by call to 'ism_get_track_id' */
	    mp4_frag_seek(ctx, con->ssp.ss_track_id, 0, con->ssp.ss_seek_offset,
			  &moof_offset, &moof_size, &moof_time);

	    if (moof_offset == 0) {
		DBG_LOG(WARNING, MOD_SSP,
			"SmoothStream Pub (State: 40): Invalid fragment offset(Off:  %ld)",
			moof_time);
		con->ssp.seek_state = 0;
		rv = -NKN_SSP_SS_ISMV_ISMA_NOT_FOUND;
                goto exit;

	    }

	    con->ssp.ssp_br_offset = moof_offset;
	    phttp->brstart = moof_offset;
	    phttp->brstop = moof_offset + 4 - 1;

	    SET_HTTP_FLAG(phttp, HRF_BYTE_RANGE);
	    DBG_LOG(MSG, MOD_SSP,
		    "SmoothStream Pub (State: 40): Refetch to parse the moof size value (Off:  %ld)",
		    phttp->brstart);

	    mp4_cleanup_ismv_ctx(ctx);
	    con->ssp.seek_state = 50;
	    rv = SSP_SEND_DATA_BACK;
	    goto exit;

	    break;

	case 50:
	    if (dataBuf != NULL) {
		box_size = get_mp4_boxsize((uint8_t *)dataBuf, 4);
		phttp->brstart += box_size;
		phttp->brstop = phttp->brstart + 4 - 1;
		SET_HTTP_FLAG(phttp, HRF_BYTE_RANGE);
		DBG_LOG(MSG, MOD_SSP,
			"SmoothStream Pub (State: 60): Refetch to parse the moof size value (Off:  %ld)",
			phttp->brstart);
		con->ssp.seek_state = 60;
		rv = SSP_SEND_DATA_BACK;
		goto exit;
	    }
	    else {
		DBG_LOG(WARNING, MOD_SSP,
			"SmoothStream Pub (State: 50): NULL dataBuf returned for ISMV media file");
		rv = -NKN_SSP_SS_NULL_BUF_INT_FETCH;
		goto exit;
	    }
	    break;

	case 60:
	    if (dataBuf != NULL) {
		box_size = get_mp4_boxsize((uint8_t *)dataBuf, 4);
		phttp->brstart = con->ssp.ssp_br_offset;
		phttp->brstop += box_size - 4 + 1;
		SET_HTTP_FLAG(phttp, HRF_BYTE_RANGE);
		SET_HTTP_FLAG(phttp, HRF_BYTE_SEEK); // To override the 206 response to 200
		CLEAR_HTTP_FLAG(phttp, HRF_SSP_NO_AM_HITS); // BZ 6541

		DBG_LOG(MSG, MOD_SSP,
			"SmoothStream Pub (State: 60): Found MOOF offset,size = %ld, %ld [Time: %ld]",
			phttp->brstart, phttp->brstop - phttp->brstart, con->ssp.ss_seek_offset);

		con->ssp.seek_state = 0;
		rv = SSP_SEND_DATA_OTW;
		goto exit;
	    }
	    else {
		DBG_LOG(WARNING, MOD_SSP,
			"SmoothStream Pub (State: 20): NULL dataBuf returned for ISMV media file");

		con->ssp.seek_state = 0;
		rv = -NKN_SSP_SS_NULL_BUF_INT_FETCH;
		goto exit;
	    }

	    break;

	default:
	    DBG_LOG(WARNING, MOD_SSP,
		    "SmoothStream Pub (State: Default): Not supported state = %d", con->ssp.seek_state);
	    rv = SSP_SEND_DATA_OTW;
            goto exit;
	    break;
    } //switch(con->ssp.seek_state)

 exit:
    return rv;
}
/*
 * PEM decode incoming data, appending SecImportRep's to specified array.
 * Returned SecImportReps may or may not have a known type and format and 
 * (if they are keys) algorithm. 
 */
OSStatus impExpParsePemToImportRefs(
	CFDataRef			importedData,
	CFMutableArrayRef	importReps,		// output appended here
	bool				*isPem)			// true means we think it was PEM regardless of 
										// final return code	
{
	/*
	 * First task: is this PEM or at least base64 encoded?
	 */
	const char *currCp = (const char *)CFDataGetBytePtr(importedData);
	const char *cp = currCp;
	unsigned lenToGo = (unsigned)CFDataGetLength(importedData);
	OSStatus ortn;
	
	*isPem = false;
	unsigned dex;
	bool allBlanks = true;
	
	for(dex=0; dex<lenToGo; dex++, cp++) {
		if (!isspace(*cp)) {
			// it's not a space.  Is it a non-ascii character?
			if (!isascii(*cp)) {
				return errSecSuccess;
			}
			
			// is it a control character?
			if (iscntrl(*cp))
			{
				return errSecSuccess;
			}
			
			// no, mark that an acceptable character was encountered and keep going
			allBlanks = false;
		}
	}

	if (allBlanks)
	{
		return errSecSuccess;
	}
	
	/* search for START line */
	const char *startLine = findStr(currCp, lenToGo, "-----BEGIN");
	if(startLine == NULL) {
		/* Assume one item, raw base64 */
		SecImpInferDbg("impExpParsePemToImportRefs no PEM headers, assuming raw base64");
		ortn = impExpImportSinglePEM(currCp, lenToGo, importReps);
		if(ortn == errSecSuccess) {
			*isPem = true;
		}
		return ortn;
	}

	/* break up input into chunks between START and END lines */
	ortn = errSecSuccess;
	bool gotSomePem = false;
	do {
		/* get to beginning of START line */
		startLine = findStr(currCp, lenToGo, "-----BEGIN");
		if(startLine == NULL) {
			break;
		}
		unsigned consumed = (unsigned)(startLine - currCp);
		assert(consumed <= lenToGo);
		lenToGo -= consumed;
		currCp  += consumed;
		
		/* get to beginning of END line */
		const char *endLine = findStr(currCp+10, lenToGo, "-----END");
		unsigned toDecode = lenToGo;
		if(endLine) {
			consumed = (unsigned)(endLine - startLine);
			assert(consumed <= lenToGo);
			currCp  += consumed;
			lenToGo -= consumed;
			
			/* find end of END line */
			const char *tmpLine = getLine(endLine, lenToGo, &consumed);
			assert((tmpLine != NULL) && (tmpLine[0] != 0));
			/* don't decode the terminators */
			toDecode = (unsigned)(endLine - startLine + strlen(tmpLine));
			free((void *)tmpLine);
			
			/* skip past END line and newlines */
			assert(consumed <= lenToGo);
			currCp  += consumed;
			lenToGo -= consumed;
		}
		else {
			/* no END line, we'll allow that - decode to end of file */
			lenToGo = 0;
		}
		
		ortn = impExpImportSinglePEM(startLine, toDecode, importReps);
		if(ortn) {
			break;
		}
		gotSomePem = true;
	} while(lenToGo != 0);
	if(ortn == errSecSuccess) {
		if(gotSomePem) {
			*isPem = true;
		}
		else {
			SecImpInferDbg("impExpParsePemToImportRefs empty at EOF, no PEM found");
			ortn = kSecFormatUnknown;
		}
	}
	return ortn;
}
/*
 * PEM decode incoming data which we've previously determined to contain
 * exactly one reasonably well formed PEM blob (it has no more than one
 * START and END line - though it may have none - and is all ASCII).
 *
 * Returned SecImportRep may or may not have a known type and format and 
 * (if it is a key) algorithm. 
 */
static OSStatus impExpImportSinglePEM(
	const char			*currCp,
	unsigned			lenToGo,
	CFMutableArrayRef	importReps)		// output appended here
{
	unsigned consumed;
	const char *currLine = NULL;		// mallocd by getLine()
	const char *lastCp = currCp;
	CFMutableArrayRef pemParamLines = NULL;
	OSStatus ortn = errSecSuccess;
	CFDataRef cdata = NULL;
	Security::KeychainCore::SecImportRep *rep = NULL;
	const char *start64;
	unsigned base64Len;	
	const char *end64;
	unsigned char *decData;
	unsigned decDataLen;
	
	/* we try to glean these from the header, but it's not fatal if we can not */
	SecExternalFormat format = kSecFormatUnknown;
	SecExternalItemType itemType = kSecItemTypeUnknown;
	CSSM_ALGORITHMS keyAlg = CSSM_ALGID_NONE;
	
	/* search to START line, parse it to get type/format/alg */
	const char *startLine = findStr(currCp, lenToGo, "-----BEGIN");
	if(startLine != NULL) {
		/* possibly skip over leading garbage */
		consumed = (unsigned)(startLine - currCp);
		lenToGo -= consumed;
		currCp = startLine;
		
		/* get C string of START line */
		currLine = getLine(startLine, lenToGo, &consumed);
		if(currLine == NULL) {
			/* somehow got here with no data */
			assert(lenToGo == 0);
			SecImpInferDbg("impExpImportSinglePEM empty data");
			ortn = errSecUnsupportedFormat;
			goto errOut;
		}
		assert(consumed <= lenToGo);
		currCp  += consumed;
		lenToGo -= consumed;

		/*
		 * Search currLine for known PEM header strings.
		 * It is not an error if we don't recognize this
		 * header.
		 */
		for(unsigned dex=0; dex<NUM_PEM_HEADERS; dex++) {
			const PemHeader *ph = &PemHeaders[dex];
			if(!strstr(currLine, ph->pemStr)) {
				continue;
			}
			/* found one! */
			format   = ph->format;
			itemType = ph->itemType;
			keyAlg   = ph->keyAlg;
			break;
		}
		
		free((void *)currLine);
	}

	/* 
	 * Skip empty lines. Save all lines containing ':' (used by openssl 
	 * to specify key wrapping parameters). These will be saved in 
	 * outgoing SecImportReps' pemParamLines.
	 */
	for( ; ; ) {
		currLine = getLine(currCp, lenToGo, &consumed);
		if(currLine == NULL || currCp == lastCp) {
			/* out of data (unable to advance to next line) */
			SecImpInferDbg("impExpImportSinglePEM out of data");
			if (currLine) free((void *)currLine);
			ortn = errSecUnsupportedFormat;
			goto errOut;
		}
		lastCp = currCp;
		
		bool skipThis = false;
		unsigned lineLen = (unsigned)strlen(currLine);
		if(lineLen == 0) {
			/* empty line */
			skipThis = true;
		}
		if(strchr(currLine, ':')) {
			/* 
			 * Save this PEM header info. Used for traditional openssl
			 * wrapped keys to indicate IV.
			 */
			SecImpInferDbg("import PEM: param line %s", currLine);
			CFStringRef cfStr = CFStringCreateWithCString(NULL, currLine,
				kCFStringEncodingASCII);
			if(pemParamLines == NULL) {
				/* first param line */
				pemParamLines = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
				
				/* 
				 * If it says "ENCRYPTED" and this is a private key,
				 * flag the fact that it's wrapped in openssl format
				 */
				if(strstr(currLine, "ENCRYPTED")) {
					if((format == kSecFormatOpenSSL) &&
					   (itemType == kSecItemTypePrivateKey)) {
						format = kSecFormatWrappedOpenSSL;
					}
				}
			}
			CFArrayAppendValue(pemParamLines, cfStr);
			CFRelease(cfStr);		// array owns it 
			skipThis = true;
		}
		free((void *)currLine);
		if(!skipThis) {
			/* looks like good stuff; process */
			break;
		}
		/* skip this line */
		assert(consumed <= lenToGo);
		currCp  += consumed;
		lenToGo -= consumed;
	}
	if(lenToGo <= 2) {
		SecImpInferDbg("impExpImportSinglePEM no valid base64 data");
		ortn = errSecUnsupportedFormat;
		goto errOut;
	}

	/* 
	 * currCP points to start of base64 data - mark it and search for end line.
	 * We skip everything after the end line.
	 */
	start64 = currCp;
	base64Len = lenToGo;			// if no END
	end64 = findStr(currCp, lenToGo, "-----END");
	if(end64 != NULL) {
		if(end64 == start64) {
			/* Empty, nothing between START and END */
			SecImpInferDbg("impExpImportSinglePEM no base64 between terminators");
			ortn = errSecUnsupportedFormat;
			goto errOut;
		}
		base64Len = (unsigned)(end64 - start64);
	}
	/* else no END, no reason to complain about that as long as base64 decode works OK */
	
	/* Base 64 decode */
	decData = cuDec64((const unsigned char *)start64, base64Len, &decDataLen);
	if(decData == NULL) {
		SecImpInferDbg("impExpImportSinglePEM bad base64 data");
		ortn = errSecUnsupportedFormat;
		goto errOut;
	}
	
	cdata = CFDataCreate(NULL, decData, decDataLen);
	free((void *)decData);
	rep = new Security::KeychainCore::SecImportRep(cdata, itemType, format, keyAlg,
		pemParamLines);
	CFArrayAppendValue(importReps, rep);
	CFRelease(cdata);		// SecImportRep holds ref
	return errSecSuccess;
	
errOut:
	if(pemParamLines != NULL) {
		CFRelease(pemParamLines);
	}
	return ortn;
}