Exemplo n.º 1
0
/* This is the lexer.  Build a token up in buf, null terminate it, and
   return a pointer to buf.  Clients must copy this out of buf before
   making any more calls to gettoken. */
static char *gettoken(reader *r) {
  int ch;

  /* If we have a valid lookahead, just return the buffer again. */
  if(r->token_la_valid) { r->token_la_valid = 0; return r->buf; }

  /* Empty the buffer */
  r->bufused = 0;


  /* Skip whitespace and comments.
     Comments begin with a ; and continue to the end of
     the line. */
  do {
    if((ch = r->char_reader(r)) == EOF)
        return NULL;
    if(ch == ';') {
      do {
        ch = r->char_reader(r);
      } while(ch != '\n' && ch != EOF);
      if(ch == EOF) return NULL;
    }
  } while(isspace(ch));
  add_to_buf(r, ch);

  /* If the token begins with one of these characters, then we know
     we are about to return. */
  if(strchr("()\'`,;", ch)) {
    if(ch == ',') {
      /* Treat ,@ as a single token.  It will be converted into
         unquote_splicing. */
      ch = r->char_reader(r);
      if(ch == '@')
        add_to_buf(r, ch);
      else
        put_back_char(r, ch);
    }
    r->buf[r->bufused] = '\0';
    return r->buf;
  }


  /* Keep reading characters until we find a whitespace or a character
     that begins a new token. */
  for(;;) {
    if((ch = r->char_reader(r)) == EOF)
        return NULL;
    if(strchr("()\'", ch) || isspace(ch)) {
      /* We have found a whitespace, a parenthesis, or a single
         quote.  Put it back, null terminate the buffer, and return. */
      put_back_char(r, ch);
      r->buf[r->bufused] = '\0';
      return r->buf;
    }
    add_to_buf(r, ch);
  }
}
Exemplo n.º 2
0
void VG_(end_msg) ( void )
{
   if (VG_(clo_logfile_fd) >= 0) {
      add_to_buf('\n');
      VG_(write)(VG_(clo_logfile_fd), vg_mbuf, VG_(strlen)(vg_mbuf));
   }
}
Exemplo n.º 3
0
void scproc(SDL_Event e, int release) {
    /*if (e.key.keysym.sym == SDLK_UP) {
        if (!release)
            dump_mem();
    } else {*/
        unsigned int scancode = get_scancode(e);
        unsigned char esc = (scancode>>8)&0xFF;
        unsigned char pkt = (scancode>>0)&0xFF;
        if (release)
            add_to_buf(0xF0);
        if (esc)
            add_to_buf(esc);
        if (pkt)
            add_to_buf(pkt);
    /*}*/
}
Exemplo n.º 4
0
void VG_(end_msg) ( void )
{
   if (VG_(clo_logfile_fd) >= 0) {
      add_to_buf('\n');
      VG_(send_bytes_to_logging_sink) ( 
         vg_mbuf, VG_(strlen)(vg_mbuf) );
   }
}
Exemplo n.º 5
0
/* main function of the polling thread
 */
static int lirc_thread(void *irctl)
{
	struct irctl *ir = irctl;
	
	lock_kernel();
	
	/* This thread doesn't need any user-level access,
	 * so get rid of all our resources
	 */
	exit_mm(current);
	exit_files(current);
	exit_fs(current);
	current->session = 1;
	current->pgrp = 1;
	current->euid = 0;
	current->tty = NULL;
	sigfillset(&current->blocked);
	
	strcpy(current->comm, "lirc_dev");
	
	unlock_kernel();
	
	if (ir->t_notify != NULL) {
		up(ir->t_notify);
	}
	
	dprintk(LOGHEAD "poll thread started\n", ir->p.name, ir->p.minor);
	
	do {
		if (ir->open) {
			if (ir->jiffies_to_wait) {
				current->state = TASK_INTERRUPTIBLE;
				schedule_timeout(ir->jiffies_to_wait);
			} else {
				interruptible_sleep_on(ir->p.get_queue(ir->p.data));
			}
			if (signal_pending(current)) {
				break;
			}
			if (!add_to_buf(ir)) {
				wake_up_interruptible(&ir->wait_poll);
			}
		} else {
			/* if device not opened so we can sleep half a second */
			current->state = TASK_INTERRUPTIBLE;
			schedule_timeout(HZ/2);
		}
	} while (!ir->shutdown && !signal_pending(current));
	
	ir->tpid = -1;
	if (ir->t_notify != NULL) {
		up(ir->t_notify);
	}
	
	dprintk(LOGHEAD "poll thread ended\n", ir->p.name, ir->p.minor);
	
	return 0;
}
Exemplo n.º 6
0
int VG_(end_msg) ( void )
{
   int count = 0;
   if (VG_(clo_log_fd) >= 0) {
      add_to_buf('\n');
      VG_(send_bytes_to_logging_sink) ( 
         vg_mbuf, VG_(strlen)(vg_mbuf) );
      count = 1;
   }
   return count;
}
Exemplo n.º 7
0
static void *reader (void *arg) {
    struct ftdi_context *handle = (struct ftdi_context *)(arg);
    unsigned char buf[0x1000];
    int br, i;

    while (1) {
        pthread_testcancel();
        br = ftdi_read_data (handle, buf, sizeof(buf));
        for (i=0; i<br; i++)
            add_to_buf (buf[i]);
    }
    return NULL;
}
Exemplo n.º 8
0
// return 0: success, message is buffered in retP->buf with retP->buf_len bytes
// return 1: read more, continue until return <=0
// error code: 
// -1: client connection error 
// -2: bad request, cannot parse request
// -3: out of resource
//
static int
handle_read( request* reqP )
{
  int r;
  char buf[1024];
  
  // Read in request from client
  r = read( reqP->conn_fd, buf, sizeof(buf) );
  add_to_buf( reqP, buf, r );
  if ( strstr( reqP->buf, "\015\012\015\012" ) == (char*) 0 &&
      strstr( reqP->buf, "\012\012" ) == (char*) 0 ) return 1;
  
  return 0;
}
Exemplo n.º 9
0
int mn_recv(int sock, char *client_message, int *mn, struct mes_buf mesbuf[100], struct timeval *timeout, fd_set *readset){
    char msg_with_n[BUFLEN], tmp[BUFLEN];
    int read_size, new_mn, buf_read_size, reason;

    while(reason = select(sock+1, readset, NULL, NULL, timeout) > 0){

    if( (read_size = recv(sock , msg_with_n, BUFLEN , 0)) > 0){
        if(strncmp(msg_with_n,"BEY",3) == 0){
            return -1;           
        }
        new_mn = get_mn(msg_with_n);
        if( (buf_read_size = get_from_buf(*mn+1, mesbuf, tmp)) > 0){
            *mn = *mn + 1;
            strcpy(client_message, tmp);
            return buf_read_size;
        }
        else{
            strcpy(tmp, msg_with_n+4);
            if( new_mn == *mn + 1){
                *mn = *mn + 1;
                strcpy(client_message, tmp);
                return strlen(client_message);
            }
            else{
                if(new_mn > *mn + 1){
                    add_to_buf(new_mn, tmp, &mesbuf[100]);
                }
                if(new_mn < *mn + 1) puts("duplicated message");
            }
        }
    }

    }
    
    if( (buf_read_size = get_from_buf(*mn+1, mesbuf, tmp)) > 0){
        *mn = *mn + 1;
        return buf_read_size;
    }
    
    return reason;

}
Exemplo n.º 10
0
static void create_dng_header(struct raw_info * raw_info){
    int i,j;
    int extra_offset;
    int raw_offset;

    struct dir_entry ifd0[]={
        {0xFE,   T_LONG,       1,  1},                                 // NewSubFileType: Preview Image
        {0x100,  T_LONG,       1,  dng_th_width},                      // ImageWidth
        {0x101,  T_LONG,       1,  dng_th_height},                     // ImageLength
        {0x102,  T_SHORT,      3,  (int)cam_PreviewBitsPerSample},     // BitsPerSample: 8,8,8
        {0x103,  T_SHORT,      1,  1},                                 // Compression: Uncompressed
        {0x106,  T_SHORT,      1,  2},                                 // PhotometricInterpretation: RGB
        {0x10E,  T_ASCII,      sizeof(dng_image_desc), (int)dng_image_desc},               // ImageDescription
        {0x10F,  T_ASCII,      sizeof(CAM_MAKE), (int)CAM_MAKE},       // Make
        {0x110,  T_ASCII,      32, (int)cam_name},                     // Model: Filled at header generation.
        {0x111,  T_LONG,       1,  0},                                 // StripOffsets: Offset
        {0x112,  T_SHORT,      1,  1},                                 // Orientation: 1 - 0th row is top, 0th column is left
        {0x115,  T_SHORT,      1,  3},                                 // SamplesPerPixel: 3
        {0x116,  T_SHORT,      1,  dng_th_height},                     // RowsPerStrip
        {0x117,  T_LONG,       1,  dng_th_width*dng_th_height*3},      // StripByteCounts = preview size
        {0x11C,  T_SHORT,      1,  1},                                 // PlanarConfiguration: 1
        {0x131,  T_ASCII|T_PTR,32, 0},                                 // Software
        {0x132,  T_ASCII,      20, (int)cam_datetime},                 // DateTime
        {0x13B,  T_ASCII|T_PTR,64, (int)dng_artist_name},              // Artist: Filled at header generation.
        {0x14A,  T_LONG,       1,  0},                                 // SubIFDs offset
        {0x8298, T_ASCII|T_PTR,64, (int)dng_copyright},                // Copyright
        {0x8769, T_LONG,       1,  0},                                 // EXIF_IFD offset
        {0x9216, T_BYTE,       4,  0x00000001},                        // TIFF/EPStandardID: 1.0.0.0
        {0xA431, T_ASCII,      sizeof(cam_serial), (int)cam_serial},         // Exif.Photo.BodySerialNumber
        {0xA434, T_ASCII,      sizeof(dng_lens_model), (int)dng_lens_model}, // Exif.Photo.LensModel
        {0xC612, T_BYTE,       4,  0x00000301},                        // DNGVersion: 1.3.0.0
        {0xC613, T_BYTE,       4,  0x00000301},                        // DNGBackwardVersion: 1.1.0.0
        {0xC614, T_ASCII,      32, (int)cam_name},                     // UniqueCameraModel. Filled at header generation.
        {0xC621, T_SRATIONAL,  9,  (int)&camera_sensor.color_matrix1},
        {0xC627, T_RATIONAL,   3,  (int)cam_AnalogBalance},
        {0xC628, T_RATIONAL,   3,  (int)cam_AsShotNeutral},
        {0xC62A, T_SRATIONAL,  1,  (int)&camera_sensor.exposure_bias},
        {0xC62B, T_RATIONAL,   1,  (int)cam_BaselineNoise},
        {0xC62C, T_RATIONAL,   1,  (int)cam_BaselineSharpness},
        {0xC62E, T_RATIONAL,   1,  (int)cam_LinearResponseLimit},
        {0xC65A, T_SHORT,      1, 21},                                 // CalibrationIlluminant1 D65
        {0xC65B, T_SHORT,      1, 21},                                 // CalibrationIlluminant2 D65 (change this if ColorMatrix2 is added)
        {0xC764, T_SRATIONAL,  1,  (int)cam_FrameRate},
    };

    struct dir_entry ifd1[]={
        {0xFE,   T_LONG,       1,  0},                                 // NewSubFileType: Main Image
        {0x100,  T_LONG|T_PTR, 1,  (int)&camera_sensor.raw_rowpix},    // ImageWidth
        {0x101,  T_LONG|T_PTR, 1,  (int)&camera_sensor.raw_rows},      // ImageLength
        {0x102,  T_SHORT|T_PTR,1,  (int)&camera_sensor.bits_per_pixel},// BitsPerSample
        {0x103,  T_SHORT,      1,  1},                                 // Compression: Uncompressed
        {0x106,  T_SHORT,      1,  0x8023},                            // PhotometricInterpretation: CFA
        {0x111,  T_LONG,       1,  0},                                 // StripOffsets: Offset
        {0x115,  T_SHORT,      1,  1},                                 // SamplesPerPixel: 1
        {0x116,  T_SHORT|T_PTR,1,  (int)&camera_sensor.raw_rows},      // RowsPerStrip
        {0x117,  T_LONG|T_PTR, 1,  (int)&camera_sensor.raw_size},      // StripByteCounts = CHDK RAW size
        {0x11A,  T_RATIONAL,   1,  (int)cam_Resolution},               // XResolution
        {0x11B,  T_RATIONAL,   1,  (int)cam_Resolution},               // YResolution
        {0x11C,  T_SHORT,      1,  1},                                 // PlanarConfiguration: 1
        {0x128,  T_SHORT,      1,  2},                                 // ResolutionUnit: inch
        {0x828D, T_SHORT,      2,  0x00020002},                        // CFARepeatPatternDim: Rows = 2, Cols = 2
        {0x828E, T_BYTE|T_PTR, 4,  (int)&camera_sensor.cfa_pattern},
        {0xC61A, T_LONG|T_PTR, 1,  (int)&camera_sensor.black_level},   // BlackLevel
        {0xC61D, T_LONG|T_PTR, 1,  (int)&camera_sensor.white_level},   // WhiteLevel
        {0xC61F, T_LONG,       2,  (int)&camera_sensor.crop.origin},
        {0xC620, T_LONG,       2,  (int)&camera_sensor.crop.size},
        {0xC68D, T_LONG,       4,  (int)&camera_sensor.dng_active_area},
        {0xC740, T_UNDEFINED|T_PTR, sizeof(badpixel_opcode),  (int)&badpixel_opcode},
    };

    struct dir_entry exif_ifd[]={
        {0x829A, T_RATIONAL,   1,  (int)cam_shutter},          // Shutter speed
        {0x829D, T_RATIONAL,   1,  (int)cam_aperture},         // Aperture
        {0x8822, T_SHORT,      1,  0},                         // ExposureProgram
        {0x8827, T_SHORT|T_PTR,1,  (int)&exif_data.iso},       // ISOSpeedRatings
        {0x9000, T_UNDEFINED,  4,  0x31323230},                // ExifVersion: 2.21
        {0x9003, T_ASCII,      20, (int)cam_datetime},         // DateTimeOriginal
        {0x9201, T_SRATIONAL,  1,  (int)cam_apex_shutter},     // ShutterSpeedValue (APEX units)
        {0x9202, T_RATIONAL,   1,  (int)cam_apex_aperture},    // ApertureValue (APEX units)
        {0x9204, T_SRATIONAL,  1,  (int)cam_exp_bias},         // ExposureBias
        {0x9205, T_RATIONAL,   1,  (int)cam_max_av},           // MaxApertureValue
        {0x9207, T_SHORT,      1,  0},                         // Metering mode
        {0x9209, T_SHORT,      1,  0},                         // Flash mode
        {0x920A, T_RATIONAL,   1,  (int)cam_focal_length},     // FocalLength
        {0x9290, T_ASCII|T_PTR,4,  (int)cam_subsectime},       // DateTime milliseconds
        {0x9291, T_ASCII|T_PTR,4,  (int)cam_subsectime},       // DateTimeOriginal milliseconds
        {0xA405, T_SHORT|T_PTR,1,  (int)&exif_data.effective_focal_length},    // FocalLengthIn35mmFilm
    };

    struct
    {
        struct dir_entry* entry;
        int count;                  // Number of entries to be saved
        int entry_count;            // Total number of entries
    } ifd_list[] = 
    {
        {ifd0,      DIR_SIZE(ifd0),     DIR_SIZE(ifd0)}, 
        {ifd1,      DIR_SIZE(ifd1),     DIR_SIZE(ifd1)}, 
        {exif_ifd,  DIR_SIZE(exif_ifd), DIR_SIZE(exif_ifd)}, 
    };

    ifd0[DNG_VERSION_INDEX].offset = BE(0x01030000);
    
    ifd1[BADPIXEL_OPCODE_INDEX].type &= ~T_SKIP;
        // Set CFAPattern value
        switch (camera_sensor.cfa_pattern)
        {
        case 0x02010100:
            badpixel_opcode[BADPIX_CFA_INDEX] = BE(1);              // BayerPhase = 1 (top left pixel is green in a green/red row)
            break;
        case 0x01020001:
            badpixel_opcode[BADPIX_CFA_INDEX] = BE(0);              // BayerPhase = 0 (top left pixel is red)
            break;
        case 0x01000201:
            badpixel_opcode[BADPIX_CFA_INDEX] = BE(3);              // BayerPhase = 3 (top left pixel is blue)
            break;
        case 0x00010102:
            badpixel_opcode[BADPIX_CFA_INDEX] = BE(2);              // BayerPhase = 2 (top left pixel is green in a green/blue row)
            break;
        }

    // filling EXIF fields
    int ifd_count = DIR_SIZE(ifd_list);

    // Fix the counts and offsets where needed
    ifd0[CAMERA_NAME_INDEX].count = ifd0[UNIQUE_CAMERA_MODEL_INDEX].count = strlen(cam_name) + 1;
    ifd0[CHDK_VER_INDEX].offset = (int)software_ver;
    ifd0[CHDK_VER_INDEX].count = strlen(software_ver) + 1;
    ifd0[ARTIST_NAME_INDEX].count = strlen(dng_artist_name) + 1;
    ifd0[COPYRIGHT_INDEX].count = strlen(dng_copyright) + 1;
    //~ ifd0[ORIENTATION_INDEX].offset = get_orientation_for_exif(exif_data.orientation);

    //~ exif_ifd[EXPOSURE_PROGRAM_INDEX].offset = get_exp_program_for_exif(exif_data.exp_program);
    //~ exif_ifd[METERING_MODE_INDEX].offset = get_metering_mode_for_exif(exif_data.metering_mode);
    //~ exif_ifd[FLASH_MODE_INDEX].offset = get_flash_mode_for_exif(exif_data.flash_mode, exif_data.flash_fired);
    //~ exif_ifd[SSTIME_INDEX].count = exif_ifd[SSTIME_ORIG_INDEX].count = strlen(cam_subsectime)+1;

    // calculating offset of RAW data and count of entries for each IFD
    raw_offset=TIFF_HDR_SIZE;

    for (j=0;j<ifd_count;j++)
    {
        raw_offset+=6; // IFD header+footer
        for(i=0; i<ifd_list[j].entry_count; i++)
        {
            if ((ifd_list[j].entry[i].type & T_SKIP) == 0)  // Exclude skipped entries (e.g. GPS info if camera doesn't have GPS)
            {
                raw_offset+=12; // IFD directory entry size
                int size_ext=get_type_size(ifd_list[j].entry[i].type)*ifd_list[j].entry[i].count;
                if (size_ext>4) raw_offset+=size_ext+(size_ext&1);
            }
        }
    }

    // creating buffer for writing data
    raw_offset=(raw_offset/512+1)*512; // exlusively for CHDK fast file writing
    dng_header_buf_size=raw_offset;
    dng_header_buf=umalloc(raw_offset);
    dng_header_buf_offset=0;
    if (!dng_header_buf) return;

    // create buffer for thumbnail
    thumbnail_buf = malloc(dng_th_width*dng_th_height*3);
    if (!thumbnail_buf)
    {
        ufree(dng_header_buf);
        dng_header_buf = 0;
        return;
    }

    //  writing offsets for EXIF IFD and RAW data and calculating offset for extra data

    extra_offset=TIFF_HDR_SIZE;

    ifd0[SUBIFDS_INDEX].offset = TIFF_HDR_SIZE + ifd_list[0].count * 12 + 6;                            // SubIFDs offset
    ifd0[EXIF_IFD_INDEX].offset = TIFF_HDR_SIZE + (ifd_list[0].count + ifd_list[1].count) * 12 + 6 + 6; // EXIF IFD offset
    ifd0[THUMB_DATA_INDEX].offset = raw_offset;                                     //StripOffsets for thumbnail
    ifd1[RAW_DATA_INDEX].offset = raw_offset + dng_th_width * dng_th_height * 3;    //StripOffsets for main image

    for (j=0;j<ifd_count;j++)
    {
        extra_offset += 6 + ifd_list[j].count * 12; // IFD header+footer
    }

    // TIFF file header

    add_val_to_buf(0x4949, sizeof(short));      // little endian
    add_val_to_buf(42, sizeof(short));          // An arbitrary but carefully chosen number that further identifies the file as a TIFF file.
    add_val_to_buf(TIFF_HDR_SIZE, sizeof(int)); // offset of first IFD

    // writing IFDs

    for (j=0;j<ifd_count;j++)
    {
        int size_ext;
        add_val_to_buf(ifd_list[j].count, sizeof(short));
        for(i=0; i<ifd_list[j].entry_count; i++)
        {
            if ((ifd_list[j].entry[i].type & T_SKIP) == 0)
            {
                add_val_to_buf(ifd_list[j].entry[i].tag, sizeof(short));
                add_val_to_buf(ifd_list[j].entry[i].type & 0xFF, sizeof(short));
                add_val_to_buf(ifd_list[j].entry[i].count, sizeof(int));
                size_ext=get_type_size(ifd_list[j].entry[i].type)*ifd_list[j].entry[i].count;
                if (size_ext<=4) 
                {
                    if (ifd_list[j].entry[i].type & T_PTR)
                    {
                        add_to_buf((void*)ifd_list[j].entry[i].offset, sizeof(int));
                    }
                    else
                    {
                        add_val_to_buf(ifd_list[j].entry[i].offset, sizeof(int));
                    }
                }
                else
                {
                    add_val_to_buf(extra_offset, sizeof(int));
                    extra_offset += size_ext+(size_ext&1);    
                }
            }
        }
        add_val_to_buf(0, sizeof(int));
    }

    // writing extra data

    for (j=0;j<ifd_count;j++)
    {
        int size_ext;
        for(i=0; i<ifd_list[j].entry_count; i++)
        {
            if ((ifd_list[j].entry[i].type & T_SKIP) == 0)
            {
                size_ext=get_type_size(ifd_list[j].entry[i].type)*ifd_list[j].entry[i].count;
                if (size_ext>4)
                {
                    add_to_buf((void*)ifd_list[j].entry[i].offset, size_ext);
                    if (size_ext&1) add_val_to_buf(0, 1);
                }
            }
        }
    }

    // writing zeros to tail of dng header (just for fun)
    for (i=dng_header_buf_offset; i<dng_header_buf_size; i++) dng_header_buf[i]=0;
}
Exemplo n.º 11
0
static void add_val_to_buf(int val, int size)
{
    add_to_buf(&val,size);
}
Exemplo n.º 12
0
int
u1db__format_range_query(int n_fields, const char **start_values,
                         const char **end_values, char **buf,
                         int *start_wildcard, int *end_wildcard)
{
    int status = U1DB_OK;
    int buf_size, i;
    char *cur = NULL;
    const char *val = NULL;
    int have_start_wildcard = 0;
    int have_end_wildcard = 0;

    if (n_fields < 1) {
        return U1DB_INVALID_PARAMETER;
    }
    // 81 for 1 doc, 166 for 2, 251 for 3
    buf_size = (1 + n_fields) * 100;
    // The first field is treated specially
    cur = (char*)calloc(buf_size, 1);
    if (cur == NULL) {
        return U1DB_NOMEM;
    }
    *buf = cur;
    add_to_buf(&cur, &buf_size, "SELECT d0.doc_id FROM document_fields d0");
    for (i = 1; i < n_fields; ++i) {
        add_to_buf(&cur, &buf_size, ", document_fields d%d", i);
    }
    add_to_buf(&cur, &buf_size, " WHERE d0.field_name = ?");
    for (i = 0; i < n_fields; ++i) {
        if (i != 0) {
            add_to_buf(&cur, &buf_size,
                " AND d0.doc_id = d%d.doc_id"
                " AND d%d.field_name = ?",
                i, i);
        }
        if (start_values != NULL) {
            val = start_values[i];
            if (val == NULL) {
                status = U1DB_INVALID_VALUE_FOR_INDEX;
                goto finish;
            }
            if (val[0] == '*') {
                start_wildcard[i] = IS_GLOB;
                have_start_wildcard= 1;
                add_to_buf(&cur, &buf_size, " and d%d.value not null", i);
            } else if (val[0] != '\0' && val[strlen(val)-1] == '*') {
                // glob
                start_wildcard[i] = ENDS_IN_GLOB;
                if (have_start_wildcard) {
                    //globs not allowed after another wildcard
                    status = U1DB_INVALID_GLOBBING;
                    goto finish;
                }
                have_start_wildcard = 1;
                add_to_buf(&cur, &buf_size, " and d%d.value >= ?", i);
            } else {
                start_wildcard[i] = NO_GLOB;
                if (have_start_wildcard) {
                    // can't have a non-wildcard after a wildcard
                    status = U1DB_INVALID_GLOBBING;
                    goto finish;
                }
                add_to_buf(&cur, &buf_size, " and d%d.value >= ?", i);
            }
        }
        if (end_values != NULL) {
            val = end_values[i];
            if (val == NULL) {
                status = U1DB_INVALID_VALUE_FOR_INDEX;
                goto finish;
            }
            if (val[0] == '*') {
                end_wildcard[i] = IS_GLOB;
                have_end_wildcard = 1;
                add_to_buf(&cur, &buf_size, " AND d%d.value NOT NULL", i);
            } else if (val[0] != '\0' && val[strlen(val)-1] == '*') {
                // glob
                end_wildcard[i] = ENDS_IN_GLOB;
                if (have_end_wildcard) {
                    //globs not allowed after another wildcard
                    status = U1DB_INVALID_GLOBBING;
                    goto finish;
                }
                have_end_wildcard = 1;
                add_to_buf(
                    &cur, &buf_size,
                    " AND (d%d.value < ? OR d%d.value GLOB ?)", i, i);
            } else {
                end_wildcard[i] = NO_GLOB;
                if (have_end_wildcard) {
                    // Can't have a non-wildcard after a wildcard
                    status = U1DB_INVALID_GLOBBING;
                    goto finish;
                }
                add_to_buf(&cur, &buf_size, " AND d%d.value <= ?", i);
            }
        }

    }
    add_to_buf(&cur, &buf_size, " ORDER BY ");
    for (i = 0; i < n_fields; ++i) {
        if (i != 0) {
            add_to_buf(&cur, &buf_size, ", ");
        }
        add_to_buf(&cur, &buf_size, "d%d.value", i);
    }
finish:
    if (status != U1DB_OK && *buf != NULL) {
        free(*buf);
        *buf = NULL;
    }
    return status;
}
Exemplo n.º 13
0
int
u1db__format_index_keys_query(int n_fields, char **buf)
{
    int status = U1DB_OK;
    int buf_size, i;
    char *cur = NULL;

    if (n_fields < 1) {
        return U1DB_INVALID_PARAMETER;
    }
    // 81 for 1 doc, 166 for 2, 251 for 3
    buf_size = (1 + n_fields) * 100;
    // The first field is treated specially
    cur = (char*)calloc(buf_size, 1);
    if (cur == NULL) {
        return U1DB_NOMEM;
    }
    *buf = cur;
    add_to_buf(&cur, &buf_size, "SELECT ");
    for (i = 0; i < n_fields; ++i) {
        if (i != 0) {
            add_to_buf(&cur, &buf_size, ", ");
        }
        add_to_buf(&cur, &buf_size, " d%d.value", i);
    }
    add_to_buf(&cur, &buf_size, " FROM ");
    for (i = 0; i < n_fields; ++i) {
        if (i != 0) {
            add_to_buf(&cur, &buf_size, ", ");
        }
        add_to_buf(&cur, &buf_size, "document_fields d%d", i);
    }
    add_to_buf(&cur, &buf_size, " WHERE d0.field_name = ?");
    for (i = 0; i < n_fields; ++i) {
        if (i != 0) {
            add_to_buf(&cur, &buf_size,
                " AND d0.doc_id = d%d.doc_id"
                " AND d%d.field_name = ?",
                i, i);
        }
        add_to_buf(&cur, &buf_size, " AND d%d.value NOT NULL", i);
    }
    add_to_buf(&cur, &buf_size, " GROUP BY ");
    for (i = 0; i < n_fields; ++i) {
        if (i != 0) {
            add_to_buf(&cur, &buf_size, ", ");
        }
        add_to_buf(&cur, &buf_size, "d%d.value", i);
    }
    if (status != U1DB_OK && *buf != NULL) {
        free(*buf);
        *buf = NULL;
    }
    return status;
}