Exemplo n.º 1
0
pfs::error_code ubjson_ostream<OStreamType, JsonType>::write_array (json_type const & j)
{
    _os << UBJSON_CHAR_ARRAY_BEGIN;

    bool use_count_optimization = ((_flags & count_optimized) && !j.empty());
    bool is_special_case = false;

    // If a type is specified, a count must also be specified.
    // A type cannot be specified by itself.
    bool use_type_optimization  = ((_flags & type_optimized) && use_count_optimization);

    // Additional checks for type optimization
    if (use_type_optimization) {

        // This call is safe. Array is not empty as checked before
        int8_t first_prefix = prefix(*j.cbegin());
        use_type_optimization = pfs::all_of(j.cbegin()
                , j.cend()
                , compare_prefix(first_prefix));

        if (use_type_optimization) {
            _os << UBJSON_CHAR_TYPE;
            _os << first_prefix;

            // Check special cases
            if (first_prefix == UBJSON_CHAR_NOOP
                    || first_prefix == UBJSON_CHAR_NULL
                    || first_prefix == UBJSON_CHAR_TRUE
                    || first_prefix == UBJSON_CHAR_FALSE) {
                is_special_case = true;
            }
        }
    }

    if (use_count_optimization) {
        _os << UBJSON_CHAR_SIZE;
        write_integer(static_cast<typename json_type::integer_type>(j.size()), true);
    }

    // Ignore special cases: strongly-typed arrays of null, no-op and boolean values
    if (! is_special_case) {
        typename json_type::const_iterator first = j.cbegin();
        typename json_type::const_iterator last  = j.cend();

        for (; first != last; ++first)
            write_json(*first, !use_type_optimization);
    }

    // If a count is specified the container must not specify an end-marker.
    if (!use_count_optimization)
        _os << UBJSON_CHAR_ARRAY_END;

    return pfs::error_code();
}
Exemplo n.º 2
0
pfs::error_code ubjson_ostream<OStreamType, JsonType>::write_object (json_type const & j)
{
    _os << UBJSON_CHAR_OBJECT_BEGIN;

    bool use_count_optimization = ((_flags & count_optimized) && !j.empty());
    bool is_special_case = false;

    // If a type is specified, a count must also be specified.
    // A type cannot be specified by itself.
    bool use_type_optimization  = ((_flags & type_optimized) && use_count_optimization);

    // Additional checks for type optimization
    if (use_type_optimization) {

        // This call is safe. Array is not empty as checked before
        int8_t first_prefix = prefix(*j.cbegin());
        use_type_optimization = pfs::all_of(j.cbegin(), j.cend(), compare_prefix(first_prefix));

        if (use_type_optimization) {
            _os << UBJSON_CHAR_TYPE;
            _os << first_prefix;

            // Check special cases
            if (first_prefix == UBJSON_CHAR_NOOP
                    || first_prefix == UBJSON_CHAR_NULL
                    || first_prefix == UBJSON_CHAR_TRUE
                    || first_prefix == UBJSON_CHAR_FALSE) {
                is_special_case = true;
            }
        }
    }

    if (use_count_optimization) {
        _os << UBJSON_CHAR_SIZE;
        write_integer(static_cast<typename json_type::integer_type>(j.size()), true);
    }

    typename json_type::const_iterator first = j.cbegin();
    typename json_type::const_iterator last = j.cend();

    if (is_special_case) {
        for (; first != last; ++first) {
            // The [S] (string) marker is omitted from each of the names in the
            // name/value pairings inside the object. The JSON specification does
            // not allow non-string name values, therefore the [S] marker
            // is redundant and must not be used.
           write_string(first.key(), false);
        }
    } else {
        for (; first != last; ++first) {
            write_string(first.key(), false);
            write_json(*first, !use_type_optimization);
        }
    }

    // If a count is specified the container must not specify an end-marker.
    if (!use_count_optimization)
        _os << UBJSON_CHAR_OBJECT_END;

    return pfs::error_code();
}
Exemplo n.º 3
0
char* wordwrap(char* inbuf, int len, int oldlen, BOOL handle_quotes)
{
	int			l;
	int			crcount=0;
	long		i,k,t;
	int			ocol=1;
	int			icol=1;
	char*		outbuf;
	char*		outp;
	char*		linebuf;
	char*		prefix=NULL;
	int			prefix_len=0;
	int			prefix_bytes=0;
	int			quote_count=0;
	int			old_prefix_bytes=0;
	int			outbuf_size=0;
	int			inbuf_len=strlen(inbuf);

	outbuf_size=inbuf_len*3+1;
	if((outbuf=(char*)malloc(outbuf_size))==NULL)
		return NULL;
	outp=outbuf;

	if((linebuf=(char*)malloc(inbuf_len+2))==NULL) { /* room for ^A codes */
		free(outbuf);
		return NULL;
	}

	if(handle_quotes) {
		if((prefix=(char *)malloc(inbuf_len+1))==NULL) { /* room for ^A codes */
			free(linebuf);
			free(outbuf);
			return NULL;
		}
		prefix[0]=0;
	}

	outbuf[0]=0;
	/* Get prefix from the first line (ouch) */
	l=0;
	i=0;
	if(handle_quotes && (quote_count=get_prefix(inbuf, &prefix_bytes, &prefix_len, len*2+2))!=0) {
		i+=prefix_bytes;
		if(prefix_len>len/3*2) {
			/* This prefix is insane (more than 2/3rds of the new width) hack it down to size */
			/* Since we're hacking it, we will always end up with a hardcr on this line. */
			/* ToDo: Something prettier would be nice. */
			sprintf(prefix," %d> ",quote_count);
			prefix_len=strlen(prefix);
			prefix_bytes=strlen(prefix);
		}
		else {
			memcpy(prefix,inbuf,prefix_bytes);
			/* Terminate prefix */
			prefix[prefix_bytes]=0;
		}
		memcpy(linebuf,prefix,prefix_bytes);
		l=prefix_bytes;
		ocol=prefix_len+1;
		icol=prefix_len+1;
		old_prefix_bytes=prefix_bytes;
	}
	for(; inbuf[i]; i++) {
		if(oldlen == 0)
			icol=-256;

		if(l>=len*2+2) {
			l-=4;
			linebuf[l]=0;
//			lprintf(LOG_CRIT, "Word wrap line buffer exceeded... munging line %s",linebuf);
		}
		switch(inbuf[i]) {
			case '\r':
				crcount++;
				break;
			case '\n':
				if(handle_quotes && (quote_count=get_prefix(inbuf+i+1, &prefix_bytes, &prefix_len, len*2+2))!=0) {
					/* Move the input pointer offset to the last char of the prefix */
					i+=prefix_bytes;
				}
				if(!inbuf[i+1]) {			/* EOF */
					linebuf[l++]='\r';
					linebuf[l++]='\n';
					outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size);
					l=0;
					ocol=1;
				}
				/* If there's a new prefix, it is a hardcr */
				else if(compare_prefix(prefix, old_prefix_bytes, inbuf+i+1-prefix_bytes, prefix_bytes)!=0) {
					if(prefix_len>len/3*2) {
						/* This prefix is insane (more than 2/3rds of the new width) hack it down to size */
						/* Since we're hacking it, we will always end up with a hardcr on this line. */
						/* ToDo: Something prettier would be nice. */
						sprintf(prefix," %d> ",quote_count);
						prefix_len=strlen(prefix);
						prefix_bytes=strlen(prefix);
					}
					else {
						memcpy(prefix,inbuf+i+1-prefix_bytes,prefix_bytes);
						/* Terminate prefix */
						prefix[prefix_bytes]=0;
					}
					linebuf[l++]='\r';
					linebuf[l++]='\n';
					outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size);
					memcpy(linebuf,prefix,prefix_bytes);
					l=prefix_bytes;
					ocol=prefix_len+1;
					old_prefix_bytes=prefix_bytes;
				}
				else if(isspace((unsigned char)inbuf[i+1])) {	/* Next line starts with whitespace.  This is a "hard" CR. */
					linebuf[l++]='\r';
					linebuf[l++]='\n';
					outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size);
					l=prefix_bytes;
					ocol=prefix_len+1;
				}
				else {
					if(icol < oldlen) {			/* If this line is overly long, It's impossible for the next word to fit */
						/* k will equal the length of the first word on the next line */
						for(k=0; inbuf[i+1+k] && (!isspace((unsigned char)inbuf[i+1+k])); k++);
						if(icol+k+1 < oldlen) {	/* The next word would have fit but isn't here.  Must be a hard CR */
							linebuf[l++]='\r';
							linebuf[l++]='\n';
							outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size);
							if(prefix)
								memcpy(linebuf,prefix,prefix_bytes);
							l=prefix_bytes;
							ocol=prefix_len+1;
						}
						else {		/* Not a hard CR... add space if needed */
							if(l<1 || !isspace((unsigned char)linebuf[l-1])) {
								linebuf[l++]=' ';
								ocol++;
							}
						}
					}
					else {			/* Not a hard CR... add space if needed */
						if(l<1 || !isspace((unsigned char)linebuf[l-1])) {
							linebuf[l++]=' ';
							ocol++;
						}
					}
				}
				icol=prefix_len+1;
				break;
			case '\x1f':	/* Delete... meaningless... strip. */
				break;
			case '\b':		/* Backspace... handle if possible, but don't go crazy. */
				if(l>0) {
					if(l>1 && linebuf[l-2]=='\x01') {
						if(linebuf[l-1]=='\x01') {
							ocol--;
							icol--;
						}
						l-=2;
					}
					else {
						l--;
						ocol--;
						icol--;
					}
				}
				break;
			case '\t':		/* TAB */
				linebuf[l++]=inbuf[i];
				/* Can't ever wrap on whitespace remember. */
				icol++;
				ocol++;
				while(ocol%8)
					ocol++;
				while(icol%8)
					icol++;
				break;
			case '\x01':	/* CTRL-A */
				linebuf[l++]=inbuf[i++];
				if(inbuf[i]!='\x01') {
					linebuf[l++]=inbuf[i];
					break;
				}
			default:
				linebuf[l++]=inbuf[i];
				ocol++;
				icol++;
				if(ocol>len && !isspace((unsigned char)inbuf[i])) {		/* Need to wrap here */
					/* Find the start of the last word */
					k=l;									/* Original next char */
					l--;									/* Move back to the last char */
					while((!isspace((unsigned char)linebuf[l])) && l>0)		/* Move back to the last non-space char */
						l--;
					if(l==0) {		/* Couldn't wrap... must chop. */
						l=k;
						while(l>1 && linebuf[l-2]=='\x01' && linebuf[l-1]!='\x01')
							l-=2;
						if(l>0 && linebuf[l-1]=='\x01')
							l--;
						if(l>0)
							l--;
					}
					t=l+1;									/* Store start position of next line */
					/* Move to start of whitespace */
					while(l>0 && isspace((unsigned char)linebuf[l]))
						l--;
					outbuf_append(&outbuf, &outp, linebuf, l+1, &outbuf_size);
					outbuf_append(&outbuf, &outp, "\r\n", 2, &outbuf_size);
					/* Move trailing words to start of buffer. */
					l=prefix_bytes;
					if(k-t>0)							/* k-1 is the last char position.  t is the start of the next line position */
						memmove(linebuf+l, linebuf+t, k-t);
					l+=k-t;
					/* Find new ocol */
					for(ocol=prefix_len+1,t=prefix_bytes; t<l; t++) {
						switch(linebuf[t]) {
							case '\x01':	/* CTRL-A */
								t++;
								if(linebuf[t]!='\x01')
									break;
								/* Fall-through */
							default:
								ocol++;
						}
					}
				}
		}
	}
	/* Trailing bits. */
	if(l) {
		linebuf[l++]='\r';
		linebuf[l++]='\n';
		outbuf_append(&outbuf, &outp, linebuf, l, &outbuf_size);
	}
	*outp=0;
	/* If there were no CRs in the input, strip all CRs */
	if(!crcount) {
		for(inbuf=outbuf; *inbuf; inbuf++) {
			if(*inbuf=='\r')
				memmove(inbuf, inbuf+1, strlen(inbuf));
		}
	}
 	free(linebuf);

	if(prefix)
		free(prefix);

	return outbuf;
}