示例#1
0
std::vector<unsigned char> CEntityWriter::SaveMatrices(long rate, std::map<std::string, std::vector<float> >& animations)
{
		std::vector<unsigned char> out;
		push_long(out, rate);
		push_long(out, 1); // 1 - matrix animation
		std::map<std::string, std::vector<float> >::iterator it = animations.begin();
		CAnimationTransformer trans;
		while (it != animations.end() ) 
		{
			char buffer[200];
			memset(buffer, 0, 200);
			std::string component_name = it->first;
			int pos= component_name.find("/");
			strncpy(buffer, component_name.c_str(), pos);
			component_name = buffer;
			
			push_string(out,buffer);
			std::vector<float>& next = it->second;
			std::vector<CKeyFrame> frames = trans.GetFrames(next);

			//out.resize(sizeof(long) + pos + sizeof(float)*next.size());
			push_long(out,frames.size());
			for (int i= 0 ; i < frames.size() ; i ++ ) 
			{
				std::vector<unsigned char> frame;
				frame.resize(sizeof(CKeyFrame));
				memcpy(&frame[0], & frames[i] , sizeof(CKeyFrame));
				out.insert(out.end(),frame.begin(), frame.end());
			}
			it++;
		}
		return out;
}
示例#2
0
std::vector<unsigned char> CEntityWriter::SaveTree(CSerializationTree& pTree)
{
	std::vector<unsigned char> data;
	push_long(data, 2); // object definition
	std::vector<unsigned char> entity = SaveEntity(pTree.m_Entity);
	push_long(data, entity.size());
	data.insert(data.end(), entity.begin() , entity.end());
	push_long(data, pTree.m_Children.size());
	for (unsigned int i = 0 ; i < pTree.m_Children.size() ; i ++ ) 
	{
		std::vector<unsigned char> subtree = SaveTree(*pTree.m_Children[i]);
		push_long(data, subtree.size());
		data.insert(data.end(), subtree.begin() , subtree.end());
	}
	return data;
}
示例#3
0
std::vector<unsigned char> CEntityWriter::SaveAnimations(long rate, CSerializationEntity& entity)
{
	std::vector<unsigned char> data;
	push_long(data, rate);
	push_long(data, 0); // 0 - bone animation
	long size = entity.m_Bones.size();
	//push_long(data, size);
	

	std::vector< CBoneSerialized >::iterator it = entity.m_Bones.begin();
	while (it != entity.m_Bones.end())
	{
		CBoneSerialized& next = (*it);
		push_long(data, (*it).m_Index);

		push_long(data,(*it).m_ID.size());
		data.insert(data.end() ,(*it).m_ID.begin() , (*it).m_ID.end());

		CAnimationTransformer trans;
	
		std::vector<CMatrix>::iterator matrices =  next.m_AnimationMatrices.begin();
		std::vector<float> f;

		while (matrices != next.m_AnimationMatrices.end())
		{
			for (int i = 0 ; i < 16 ; i ++ ) f.push_back( matrices->m[i]);
			matrices++;
		}
		std::vector<CKeyFrame> frames = trans.GetFrames(f);
		//out.resize(sizeof(long) + pos + sizeof(float)*next.size());
		push_long(data,frames.size());
		for (int i= 0 ; i < frames.size() ; i ++ ) 
		{
			std::vector<unsigned char> frame;
			frame.resize(sizeof(CKeyFrame));
			memcpy(&frame[0], & frames[i] , sizeof(CKeyFrame));
			data.insert(data.end(),frame.begin(), frame.end());
		}

		it ++;
	}
	return data;


}
示例#4
0
std::vector<unsigned char> CEntityWriter::SaveMaterials(CSerializationEntity& entity)
{
	std::vector<unsigned char> data;
	
	push_long(data, entity.m_Materials.size());
	std::vector<CRenderable_ExportMaterial>::iterator it = entity.m_Materials.begin();
	while (it !=  entity.m_Materials.end())
	{
		push_long(data, (*it).m_Name.size());
		data.insert(data.end() ,(*it).m_Name.begin() , (*it).m_Name.end());
		long diffSource = (*it).m_DiffuseSource;
		long wrapU = (*it).m_WrapU;
		long wrapV = (*it).m_WrapV;
		push_long(data, diffSource);
		push_long(data, wrapU);
		push_long(data, wrapV);
		push_long(data, (*it).m_DiffuseColor);
		push_long(data, (*it).m_File.size());
		data.insert(data.end() ,(*it).m_File.begin() , (*it).m_File.end());
		
		it++;
	}
	return data;
}
示例#5
0
std::vector<unsigned char> CEntityWriter::SaveEntity(CSerializationEntity& pRoot)
{
	std::vector<unsigned char> data;

	// save mesh information. 
	long magic = 0; // static mesh is being saved.
	if (pRoot.m_Bones.size() > 0 ) 
	{
		magic = 1; // animated mesh is being saved.
	}
	push_long(data, magic);
	push_matrix(data, pRoot.m_Pos);
	assert(pRoot.m_EntityName.size()> 0);
	const char * cStr = pRoot.m_EntityName.c_str();

	push_string(data, pRoot.m_EntityName);
	
	push_float(data, pRoot.globalScale);

	// save mesh information
	std::vector<CRenderable_Export >  v = pRoot.m_ExportShapes;
	long num_renderables = v.size();
	push_long(data, num_renderables);
	for (int i= 0 ; i < num_renderables ; i ++ ) 
	{
		const CRenderable_Export& pRenderable  = v[i];
		push_long(data, pRenderable.m_UsedBones.size() );
		append(pRenderable.m_UsedBones, data);
		push_long(data, pRenderable.m_Geometries.size() );
		for (int geomIndex = 0; geomIndex < pRenderable.m_Geometries.size() ; geomIndex ++ ) 
		{
			
			const CRenderable_AbstractGeometry&  pGeometry = pRenderable.m_Geometries[geomIndex];
			push_long(data, pGeometry.m_VertexBuffers.size());	
			for (unsigned int j = 0 ; j < pGeometry.m_VertexBuffers.size() ; j ++ ) 
			{
				std::vector<unsigned char> vertexes;
				const CRenderable_AbstractVertexBuffer& pBuffer = pGeometry.m_VertexBuffers[j];
				vertexes = SaveVertexes(pBuffer);
				long size = vertexes.size();
				push_long(data, size);
				append(vertexes, data);			
			}
			push_long(data, pGeometry.m_IndexBuffers.size());	
			for (unsigned int j = 0 ; j < pGeometry.m_IndexBuffers.size() ; j ++ ) 
			{
				std::vector<unsigned char> indexes;
				const CRenderable_AbstractIndexBuffer& pIndex = pGeometry.m_IndexBuffers[j];
				indexes = SaveIndexes(pIndex);
				long size = indexes.size();
				push_long(data, size);
				append(indexes, data);

			}
			push_long(data,  pGeometry.m_RenderCalls.size());	
			for (unsigned int j = 0 ; j < pGeometry.m_RenderCalls.size() ; j ++ ) 
			{
				std::vector<unsigned char> calls;
				const CRenderable_AbstractRenderCall& pCall = pGeometry.m_RenderCalls[j];
				calls = SaveRenderCalls(pCall);
				long size = calls.size();
				push_long(data, size);
				append(calls, data);
			
			}
		}
		push_long(data, pRenderable.m_ExportMaterial.m_Name.size());
		for (unsigned int i = 0 ; i < pRenderable.m_ExportMaterial.m_Name.size() ; i ++ ) 
		{
			data.push_back(pRenderable.m_ExportMaterial.m_Name[i]);
		}
	}
	// save static bone information
	push_long(data, pRoot.m_Bones.size());
	
	std::vector<CBoneSerialized>& bonez =  pRoot.m_Bones;
	std::vector<CBoneSerialized>::iterator it = bonez.begin();
	while (it != pRoot.m_Bones.end())
	{
		/*
			CBoneSerialized* m_pParent;
			std::list<CBoneSerialized*> m_ChildrenPtr;
			CMatrix m_InitialMatrix;
			CMatrix m_InvBoneSkinMatrix;
			CMatrix m_FinalMatrix;
			CVector m_Pos;
			long m_Index;
			std::string m_ID;
			std::list<CMatrix> m_AnimationMatrices;
		*/
		long parentIndex = -1;
		if ((*it).m_pParent >= 0)
		{
			parentIndex = bonez[(*it).m_pParent].m_Index;
		}
		push_long(data, parentIndex);

		std::vector<unsigned char> matrixVector;
		matrixVector.resize(sizeof(CMatrix));
		

		memcpy(&matrixVector[0] , &(*it).m_InitialMatrix, sizeof(CMatrix));
		data.insert(data.end() , matrixVector.begin(), matrixVector.end());

		memcpy(&matrixVector[0] ,&(*it).m_InvBoneSkinMatrix, sizeof(CMatrix));
		data.insert(data.end() , matrixVector.begin(), matrixVector.end());

	
		push_long(data,(*it).m_Index);
		push_long(data,(*it).m_ID.size());
		assert( (*it).m_ID.size() < 100 ) ;
		CBoneSerialized& pBone = (*it);
		data.insert(data.end(), pBone.m_ID.begin(), pBone.m_ID.end());
		//data.insert(data.end() ,(*it)->m_ID.begin() , (*it)->m_ID.end());
		/*push_long(data, (*it)->m_MatrixMapping.size() );
		
		for (int i = 0 ; i < (*it)->m_MatrixMapping.size() ; i ++ ) 
		{
			data.push_back( (*it)->m_MatrixMapping[i].first );
			data.push_back( (*it)->m_MatrixMapping[i].second );
		}*/
		//PrintBone(*it);
		it++;
	}



	return data;
}
示例#6
0
文件: config_parser.c 项目: smrt28/i3
struct ConfigResultIR *parse_config(const char *input, struct context *context) {
    /* Dump the entire config file into the debug log. We cannot just use
     * DLOG("%s", input); because one log message must not exceed 4 KiB. */
    const char *dumpwalk = input;
    int linecnt = 1;
    while (*dumpwalk != '\0') {
        char *next_nl = strchr(dumpwalk, '\n');
        if (next_nl != NULL) {
            DLOG("CONFIG(line %3d): %.*s\n", linecnt, (int)(next_nl - dumpwalk), dumpwalk);
            dumpwalk = next_nl + 1;
        } else {
            DLOG("CONFIG(line %3d): %s\n", linecnt, dumpwalk);
            break;
        }
        linecnt++;
    }
    state = INITIAL;
    statelist_idx = 1;

    /* A YAJL JSON generator used for formatting replies. */
    command_output.json_gen = yajl_gen_alloc(NULL);

    y(array_open);

    const char *walk = input;
    const size_t len = strlen(input);
    int c;
    const cmdp_token *token;
    bool token_handled;
    linecnt = 1;

// TODO: make this testable
#ifndef TEST_PARSER
    cfg_criteria_init(&current_match, &subcommand_output, INITIAL);
#endif

    /* The "<=" operator is intentional: We also handle the terminating 0-byte
     * explicitly by looking for an 'end' token. */
    while ((size_t)(walk - input) <= len) {
        /* Skip whitespace before every token, newlines are relevant since they
         * separate configuration directives. */
        while ((*walk == ' ' || *walk == '\t') && *walk != '\0')
            walk++;

        //printf("remaining input: %s\n", walk);

        cmdp_token_ptr *ptr = &(tokens[state]);
        token_handled = false;
        for (c = 0; c < ptr->n; c++) {
            token = &(ptr->array[c]);

            /* A literal. */
            if (token->name[0] == '\'') {
                if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) {
                    if (token->identifier != NULL)
                        push_string(token->identifier, token->name + 1);
                    walk += strlen(token->name) - 1;
                    next_state(token);
                    token_handled = true;
                    break;
                }
                continue;
            }

            if (strcmp(token->name, "number") == 0) {
                /* Handle numbers. We only accept decimal numbers for now. */
                char *end = NULL;
                errno = 0;
                long int num = strtol(walk, &end, 10);
                if ((errno == ERANGE && (num == LONG_MIN || num == LONG_MAX)) ||
                    (errno != 0 && num == 0))
                    continue;

                /* No valid numbers found */
                if (end == walk)
                    continue;

                if (token->identifier != NULL)
                    push_long(token->identifier, num);

                /* Set walk to the first non-number character */
                walk = end;
                next_state(token);
                token_handled = true;
                break;
            }

            if (strcmp(token->name, "string") == 0 ||
                strcmp(token->name, "word") == 0) {
                const char *beginning = walk;
                /* Handle quoted strings (or words). */
                if (*walk == '"') {
                    beginning++;
                    walk++;
                    while (*walk != '\0' && (*walk != '"' || *(walk - 1) == '\\'))
                        walk++;
                } else {
                    if (token->name[0] == 's') {
                        while (*walk != '\0' && *walk != '\r' && *walk != '\n')
                            walk++;
                    } else {
                        /* For a word, the delimiters are white space (' ' or
                         * '\t'), closing square bracket (]), comma (,) and
                         * semicolon (;). */
                        while (*walk != ' ' && *walk != '\t' &&
                               *walk != ']' && *walk != ',' &&
                               *walk != ';' && *walk != '\r' &&
                               *walk != '\n' && *walk != '\0')
                            walk++;
                    }
                }
                if (walk != beginning) {
                    char *str = scalloc(walk - beginning + 1);
                    /* We copy manually to handle escaping of characters. */
                    int inpos, outpos;
                    for (inpos = 0, outpos = 0;
                         inpos < (walk - beginning);
                         inpos++, outpos++) {
                        /* We only handle escaped double quotes to not break
                         * backwards compatibility with people using \w in
                         * regular expressions etc. */
                        if (beginning[inpos] == '\\' && beginning[inpos + 1] == '"')
                            inpos++;
                        str[outpos] = beginning[inpos];
                    }
                    if (token->identifier)
                        push_string(token->identifier, str);
                    free(str);
                    /* If we are at the end of a quoted string, skip the ending
                     * double quote. */
                    if (*walk == '"')
                        walk++;
                    next_state(token);
                    token_handled = true;
                    break;
                }
            }

            if (strcmp(token->name, "line") == 0) {
                while (*walk != '\0' && *walk != '\n' && *walk != '\r')
                    walk++;
                next_state(token);
                token_handled = true;
                linecnt++;
                walk++;
                break;
            }

            if (strcmp(token->name, "end") == 0) {
                //printf("checking for end: *%s*\n", walk);
                if (*walk == '\0' || *walk == '\n' || *walk == '\r') {
                    next_state(token);
                    token_handled = true;
/* To make sure we start with an appropriate matching
                     * datastructure for commands which do *not* specify any
                     * criteria, we re-initialize the criteria system after
                     * every command. */
// TODO: make this testable
#ifndef TEST_PARSER
                    cfg_criteria_init(&current_match, &subcommand_output, INITIAL);
#endif
                    linecnt++;
                    walk++;
                    break;
                }
            }
        }

        if (!token_handled) {
            /* Figure out how much memory we will need to fill in the names of
             * all tokens afterwards. */
            int tokenlen = 0;
            for (c = 0; c < ptr->n; c++)
                tokenlen += strlen(ptr->array[c].name) + strlen("'', ");

            /* Build up a decent error message. We include the problem, the
             * full input, and underline the position where the parser
             * currently is. */
            char *errormessage;
            char *possible_tokens = smalloc(tokenlen + 1);
            char *tokenwalk = possible_tokens;
            for (c = 0; c < ptr->n; c++) {
                token = &(ptr->array[c]);
                if (token->name[0] == '\'') {
                    /* A literal is copied to the error message enclosed with
                     * single quotes. */
                    *tokenwalk++ = '\'';
                    strcpy(tokenwalk, token->name + 1);
                    tokenwalk += strlen(token->name + 1);
                    *tokenwalk++ = '\'';
                } else {
                    /* Skip error tokens in error messages, they are used
                     * internally only and might confuse users. */
                    if (strcmp(token->name, "error") == 0)
                        continue;
                    /* Any other token is copied to the error message enclosed
                     * with angle brackets. */
                    *tokenwalk++ = '<';
                    strcpy(tokenwalk, token->name);
                    tokenwalk += strlen(token->name);
                    *tokenwalk++ = '>';
                }
                if (c < (ptr->n - 1)) {
                    *tokenwalk++ = ',';
                    *tokenwalk++ = ' ';
                }
            }
            *tokenwalk = '\0';
            sasprintf(&errormessage, "Expected one of these tokens: %s",
                      possible_tokens);
            free(possible_tokens);

            /* Go back to the beginning of the line */
            const char *error_line = start_of_line(walk, input);

            /* Contains the same amount of characters as 'input' has, but with
             * the unparseable part highlighted using ^ characters. */
            char *position = scalloc(strlen(error_line) + 1);
            const char *copywalk;
            for (copywalk = error_line;
                 *copywalk != '\n' && *copywalk != '\r' && *copywalk != '\0';
                 copywalk++)
                position[(copywalk - error_line)] = (copywalk >= walk ? '^' : (*copywalk == '\t' ? '\t' : ' '));
            position[(copywalk - error_line)] = '\0';

            ELOG("CONFIG: %s\n", errormessage);
            ELOG("CONFIG: (in file %s)\n", context->filename);
            char *error_copy = single_line(error_line);

            /* Print context lines *before* the error, if any. */
            if (linecnt > 1) {
                const char *context_p1_start = start_of_line(error_line - 2, input);
                char *context_p1_line = single_line(context_p1_start);
                if (linecnt > 2) {
                    const char *context_p2_start = start_of_line(context_p1_start - 2, input);
                    char *context_p2_line = single_line(context_p2_start);
                    ELOG("CONFIG: Line %3d: %s\n", linecnt - 2, context_p2_line);
                    free(context_p2_line);
                }
                ELOG("CONFIG: Line %3d: %s\n", linecnt - 1, context_p1_line);
                free(context_p1_line);
            }
            ELOG("CONFIG: Line %3d: %s\n", linecnt, error_copy);
            ELOG("CONFIG:           %s\n", position);
            free(error_copy);
            /* Print context lines *after* the error, if any. */
            for (int i = 0; i < 2; i++) {
                char *error_line_end = strchr(error_line, '\n');
                if (error_line_end != NULL && *(error_line_end + 1) != '\0') {
                    error_line = error_line_end + 1;
                    error_copy = single_line(error_line);
                    ELOG("CONFIG: Line %3d: %s\n", linecnt + i + 1, error_copy);
                    free(error_copy);
                }
            }

            context->has_errors = true;

            /* Format this error message as a JSON reply. */
            y(map_open);
            ystr("success");
            y(bool, false);
            /* We set parse_error to true to distinguish this from other
             * errors. i3-nagbar is spawned upon keypresses only for parser
             * errors. */
            ystr("parse_error");
            y(bool, true);
            ystr("error");
            ystr(errormessage);
            ystr("input");
            ystr(input);
            ystr("errorposition");
            ystr(position);
            y(map_close);

            /* Skip the rest of this line, but continue parsing. */
            while ((size_t)(walk - input) <= len && *walk != '\n')
                walk++;

            free(position);
            free(errormessage);
            clear_stack();

            /* To figure out in which state to go (e.g. MODE or INITIAL),
             * we find the nearest state which contains an <error> token
             * and follow that one. */
            bool error_token_found = false;
            for (int i = statelist_idx - 1; (i >= 0) && !error_token_found; i--) {
                cmdp_token_ptr *errptr = &(tokens[statelist[i]]);
                for (int j = 0; j < errptr->n; j++) {
                    if (strcmp(errptr->array[j].name, "error") != 0)
                        continue;
                    next_state(&(errptr->array[j]));
                    error_token_found = true;
                    break;
                }
            }

            assert(error_token_found);
        }
    }
示例#7
0
文件: main.c 项目: DSMan195276/i3
static char *rewrite_binding(const char *input) {
    state = INITIAL;
    statelist_idx = 1;

    const char *walk = input;
    const size_t len = strlen(input);
    int c;
    const cmdp_token *token;
    char *result = NULL;

    /* The "<=" operator is intentional: We also handle the terminating 0-byte
     * explicitly by looking for an 'end' token. */
    while ((walk - input) <= len) {
        /* Skip whitespace before every token, newlines are relevant since they
         * separate configuration directives. */
        while ((*walk == ' ' || *walk == '\t') && *walk != '\0')
            walk++;

		//printf("remaining input: %s\n", walk);

        cmdp_token_ptr *ptr = &(tokens[state]);
        for (c = 0; c < ptr->n; c++) {
            token = &(ptr->array[c]);

            /* A literal. */
            if (token->name[0] == '\'') {
                if (strncasecmp(walk, token->name + 1, strlen(token->name) - 1) == 0) {
                    if (token->identifier != NULL)
                        push_string(token->identifier, token->name + 1);
                    walk += strlen(token->name) - 1;
                    if ((result = next_state(token)) != NULL)
                        return result;
                    break;
                }
                continue;
            }

            if (strcmp(token->name, "number") == 0) {
                /* Handle numbers. We only accept decimal numbers for now. */
                char *end = NULL;
                errno = 0;
                long int num = strtol(walk, &end, 10);
                if ((errno == ERANGE && (num == LONG_MIN || num == LONG_MAX)) ||
                    (errno != 0 && num == 0))
                    continue;

                /* No valid numbers found */
                if (end == walk)
                    continue;

                if (token->identifier != NULL)
                    push_long(token->identifier, num);

                /* Set walk to the first non-number character */
                walk = end;
                if ((result = next_state(token)) != NULL)
                    return result;
                break;
            }

            if (strcmp(token->name, "string") == 0 ||
                strcmp(token->name, "word") == 0) {
                const char *beginning = walk;
                /* Handle quoted strings (or words). */
                if (*walk == '"') {
                    beginning++;
                    walk++;
                    while (*walk != '\0' && (*walk != '"' || *(walk-1) == '\\'))
                        walk++;
                } else {
                    if (token->name[0] == 's') {
                        while (*walk != '\0' && *walk != '\r' && *walk != '\n')
                            walk++;
                    } else {
                        /* For a word, the delimiters are white space (' ' or
                         * '\t'), closing square bracket (]), comma (,) and
                         * semicolon (;). */
                        while (*walk != ' ' && *walk != '\t' &&
                               *walk != ']' && *walk != ',' &&
                               *walk !=  ';' && *walk != '\r' &&
                               *walk != '\n' && *walk != '\0')
                            walk++;
                    }
                }
                if (walk != beginning) {
                    char *str = scalloc(walk-beginning + 1);
                    /* We copy manually to handle escaping of characters. */
                    int inpos, outpos;
                    for (inpos = 0, outpos = 0;
                         inpos < (walk-beginning);
                         inpos++, outpos++) {
                        /* We only handle escaped double quotes to not break
                         * backwards compatibility with people using \w in
                         * regular expressions etc. */
                        if (beginning[inpos] == '\\' && beginning[inpos+1] == '"')
                            inpos++;
                        str[outpos] = beginning[inpos];
                    }
                    if (token->identifier)
                        push_string(token->identifier, str);
                    free(str);
                    /* If we are at the end of a quoted string, skip the ending
                     * double quote. */
                    if (*walk == '"')
                        walk++;
                    if ((result = next_state(token)) != NULL)
                        return result;
                    break;
                }
            }

            if (strcmp(token->name, "end") == 0) {
                //printf("checking for end: *%s*\n", walk);
                if (*walk == '\0' || *walk == '\n' || *walk == '\r') {
                    if ((result = next_state(token)) != NULL)
                        return result;
                    /* To make sure we start with an appropriate matching
                     * datastructure for commands which do *not* specify any
                     * criteria, we re-initialize the criteria system after
                     * every command. */
                    // TODO: make this testable
                    walk++;
                    break;
               }
           }
        }
    }

    return NULL;
}